2011-08-28 6 views
45

Noteというクラスがあり、これにはtime_spentというインスタンス変数が含まれています。クラスでEnumerable mixinを使用するにはどうすればよいですか?

current_user.notes.inject{|total_time_spent,note| total_time_spent + note.time_spent} 

Enumerable moduleに混合することによって、このことが可能です:私はこのような何かを行うことができるようにしたいですか?私はクラスにinclude Enumerableを追加してからeachメソッドを定義するはずですが、各メソッドはクラスメソッドかインスタンスメソッドであるべきですか? eachメソッドには何が入りますか?私はRubyの1.9.2

+1

はすみません?あなたの例は、マイナーな変更で既に実行できます: 'current_user.notes.inject(0){| total_time_spent、note | total_time_spent + note.time_spent} ' –

+0

また、' current_user.notes.sum(&:time_spent) ' – aidan

答えて

75

を使用してい

それは、ただ簡単Enumerableモジュールを含む、より多くの場合よりも、単に他のクラスのeachメソッドを使用しますないeachインスタンスメソッドを定義しています。ここでは本当に簡単な例です:Ruby Enumerable Magic: The Basics:更なる情報については

class ATeam 
    include Enumerable 

    def initialize(*members) 
    @members = members 
    end 

    def each(&block) 
    @members.each do |member| 
     block.call(member) 
    end 
    # or 
    # @members.each(&block) 
    end 
end 

ateam = ATeam.new("Face", "B.A. Barracus", "Murdoch", "Hannibal") 
#use any Enumerable method from here on 
p ateam.map(&:downcase) 

、私は次の記事をお勧めします。

あなたの質問の文脈では、アクセサーを介して公開しているものが既にコレクションの場合は、恐らくEnumerableを含むことを心配する必要はありません。

+0

の場合は、' block.call(member) 'の代わりに' yield member'と言うこともできます。 –

+2

私が明示的なブロック引数を使用する私はprocオブジェクトで作業することを好む。個人的には、 'call 'の' [] 'エイリアスを通常使う(' block [member] ')が、OPのために混乱するかもしれないと思った。 –

+11

なぜ単純に '@ members.each(&block)'ではないのですか? – tokland

1

可算ドキュメンテーションは以下のサイス:

可算ミックスインは、いくつかの トラバーサルと検索方法で、およびソートする機能を持つコレクションクラスを提供します。 クラスは、それぞれのメソッドを提供する必要があります。このメソッドでは、コレクションの という連続したメンバーが生成されます。 列挙#最大#min、または#sortが使用されている場合、これらのメソッドは、メンバーの間で順序に依存している として、コレクション内のオブジェクト も、意味のある< =>演算子を実装する必要があります。コレクション。

これは、トリックを行います< =>を実装することを意味します。

を参照してください:私の質問は無知ですが、あなたはより多くの何もする必要はありなぜ以来 `current_user.notes`が、それはすでに列挙含ま意味、既に配列である場合Enumerable

関連する問題