3

この質問は StackOverflow にとっては哲学的すぎるかもしれませんが、機能を拡張するために組み込みクラスをベースクラス化することが「良い」Ruby スタイルと見なされるかどうか疑問に思っています。

例えば

class Grades < Array
  def sum
    sum = 0
    self.each do |num|
      sum += num
    end
    return sum
  end
  def avg
    self.sum/self.length
  end
end

Grades オブジェクトは、ビルドすると配列のように見えますが、アクセスしたい追加の sum 関数と avg 関数があります。配列をベースクラスにするのではなく、この機能を汎用オブジェクトに追加するのが「より良い」スタイルでしょうか?

4

3 に答える 3

8

はい。

一般に、誰もが Ruby のすべてに自由に「モンキー パッチ」を適用します。あなたが書いたクラスから、あなたが書いたよりも重要なクラス、ライブラリ クラスまでです。

ただし、一般的なコンピューティング スタイルのガイドラインは、クラスがすべてを実行する場合、クラスは何も実行しないというものです。あなたの例は効率的にアクセスeach()します、新しいクラスはすべてのメソッドを公開するようになりました。これには、〜と呼ばれたくないものや、クレチンがいつか行ってモンキーパッチを適用する可能性のあるものも含まれます! したがって、クラスが非常に公開されている (プログラム全体で使用されている) 場合は、委譲を検討することをお勧めします。length()Grades ArrayGrades

別のガイドライン (一部の言語では他の言語よりも多く適用されます) は、ポリモーフィズムを実現するためにメソッドをオーバーライドしない限り、決して継承してはならないというものです。私を含む Ruby コミュニティ全体が自由に破ることを楽しんでいる、もう 1 つのルールです。

于 2013-05-12T05:09:59.863 に答える
4

この場合、サブクラス化はあまり適切ではないと思います。サブクラスは、そのスーパークラスのより具体的なバージョンである必要がFixnumありIntegerますNumeric。のようなものですObject(数値を表すオブジェクトのみが数値です)。Grades一方、あなたのクラスは、Arrayそれ自体についてさらにいくつかのことを計算できることを除いて、 とまったく同じです。

格納するデータについて何らかの制約がある場合Grades(たとえば、0.0 から 1.0 までの数値 (または、必要に応じて 0 から 100 までの整数) のみを挿入できるようにするなど) は、 をサブクラス化することに意味があるかもしれませんArray。一方、直接GradesサブクラスObjectを持ち、実際の成績をArray属性に保持することも理にかなっている場合があります。

一方、 と を追加するsumavg、他の種類の配列にも同様に役立つ機能が追加されるだけです。このような一般的な機能については、単にこれらのメソッドを に追加するだけなので、特定の場所にプレーンがあるのかArray​​ があるのか​​を心配する必要はありません。ArrayGrades

もちろん、ここにはグレーな領域がいくつかあります —letter成績を A から F の成績文字に変換するメソッドを追加することを提案している場合、私は をサブクラス化することにそれほど消極的ではありませんGrades。これは間違いなく審判です。しかし、このレベルの汎用性については、サブクラス化は適切ではないと思います。

于 2013-05-12T05:31:39.263 に答える
0

Ruby では、モラルはより自由です。許容されるのは、プログラマーがそのように判断するものです。実際、既存のクラスにモンキー パッチを適用することは、ほぼ標準的な方法です。他の2つの回答が言ったこととは別に、Ruby 2.0refineの機能に注意を向けさせてください。これにより、他のコードとの望ましくない相互作用を恐れずに、より厳密な境界内でモンキーパッチを適用できます.

Gradesしかし、あなたの特定のケースでは、別のクラスを作成するというあなたの決定は正しいものかもしれないと思います. それは単なる直感です。確実に言うには、コードベースに精通している必要があります。Gradesクラスを のサブクラスにするか、実際の成績を格納し、クラスから必要なメソッドを委譲するArray属性を単に与えるかどうかは、それほど重要ではありません。@grade_arrayArray

于 2013-05-12T12:37:41.763 に答える