1

私はRubyを初めて使用します。すべての範囲、配列、ハッシュ、つまりすべての列挙型に対して機能するmethod_missingを使用して単一の「defArray / Range / Hash」を作成する方法はありますか?たとえば、次のように機能するはずです。

[1..5].Sum()  
[1,2,3,5].Sum()  
{'x' => 1, 'y' = 4}.Sum()  

Sum()は、method_missing内で定義されたカスタムメソッドです。今のところ、Array、Range、Hashのmethod_missingを別々に処理する3つの異なる関数を作成しました。

4

2 に答える 2

4

モジュールを開き、それにインスタンスメソッドを追加することmethod_missingで、すべてのEnumerableを定義できます。Enumerable

module Enumerable
  def method_missing *args
    puts 'hi'
  end
end

[].hithere # => hi

ただし、このロジックを次のように追加するのではなく、具体的なsumメソッド(Rubyメソッドの命名ガイドラインに従って小文字で始まる)を定義することをお勧めします。method_missing

module Enumerable
  def sum
    # your implementation
  end
end

[].sum
于 2012-03-11T10:28:43.957 に答える
0

Alexが言ったように、最良の方法はEnumerableに対して独自のメソッド#sumを定義することですが、各Enumerableには#eachがあるはずですが、生成される結果はサブクラスごとに異なります。たとえば、ハッシュはキーと値のペアを生成します。これは、単一の#sumメソッドが処理方法を知っている必要があります。

これがその方法の一例です。着信引数を配列にスプラットしようとし、合計には配列の最後の要素のみが含まれます。これは、ハッシュ、配列、および範囲で機能します(ただし、おそらく1.9でのみ機能します)

module Enumerable
  def sum
    r = 0
    each {|(*x)| r += x.last}
    r
  end
end

または、#each_for_sumのように、Enumerableごとに独自の反復メソッドを定義し、#sumにそのメソッドを使用して合計を実行させることもできます。ただし、おそらく、異なるEnumerableに対していくつかのバージョンの#each_for_sumを作成する必要があります(たとえば、デフォルトの#each_for_sumは単にEnumerable#eachになりますが、Hash#each_for_sumは値だけを生成します)。

module Enumerable
  def sum
    r = 0
    each_for_sum {|x| r += x}
    r
  end

  def each_for_sum &block
     each(&block)
  end
end

class Hash
  def each_for_sum
    values.each {|x| yield x}
  end
end
于 2012-03-11T10:52:43.313 に答える