2012-03-11 9 views
1

Rubyを初めて使用しています。すべてのレンジ、配列、ハッシュで動作するmethod_missingを持つ単一の 'def Array/Range/Hash'を書く方法はありますか?Enumerables?例えば、以下の作業をする必要があります:Array、Hash、Rangeの1つのメソッド_Missing

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

合計()method_missing内を定義し当社独自の方法です。現在、Array、Range、およびHashのmethod_missingを別々に扱う3つの関数を記述しています。あなたはEnumerableモジュールを開いて、そこにインスタンスメソッドを追加することによって、すべてのEnumerablesためmethod_missingを定義することができます

答えて

4

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 
0

アレックスは最良の方法は、単に列挙、0のための独自のメソッドの#sumを定義するだろうと述べたようにしかし、各Enumerableは#eachを持つはずですが、それは各サブクラスごとに異なります。たとえば、ハッシュはキーと値のペアを生成します。これは、単一の#sumメソッドが対処する方法を知っている必要があります。

ここでは、入力引数を配列にスプライトしようとする例を示します。合計には配列の最後の要素のみが含まれます。これはまた、あなたが#each_for_sumのように、各可算のために、独自の反復メソッドを定義し、#sumは、加算を行うには、そのメソッドを使用してみましょうことができハッシュ、配列と範囲(ただし、それはおそらく唯一の1.9で動作します)

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

のために働きます。しかし、おそらく#each_for_sumのいくつかのバージョンを異なるEnumerableに書く必要があります(たとえば、デフォルトの#each_for_sumはそれぞれEnumerable#になりますが、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 
関連する問題