How do I use the Enumerable mixin in my class?
RubyRuby Problem Overview
I have a class called Note
, which includes an instance variable called time_spent
. I want to be able to do something like this:
current_user.notes.inject{|total_time_spent,note| total_time_spent + note.time_spent}
Is this possible by mixing in the Enumerable module? I know you are supposed to do add include Enumerable
to the class and then define an each
method, but should the each method be a class or instance method? What goes in the each
method?
I'm using Ruby 1.9.2
Ruby Solutions
Solution 1 - Ruby
It's easy, just include the Enumerable
module and define an each
instance method, which more often than not will just use some other class's each
method. Here's a really simplified example:
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)
For further info, I recommend the following article: Ruby Enumerable Magic: The Basics.
In the context of your question, if what you expose through an accessor already is a collection, you probably don't need to bother with including Enumerable
.
Solution 2 - Ruby
The Enumerable documentations says the following:
> The Enumerable mixin provides collection classes with several > traversal and searching methods, and with the ability to sort. The > class must provide a method each, which yields successive members of > the collection. If Enumerable#max, #min, or #sort is used, the objects > in the collection must also implement a meaningful <=> operator, as > these methods rely on an ordering between members of the collection.
This means implementing each
on the collection. If you're interested in using #max
, #min
or #sort
you should implement <=>
on its members.
See: Enumerable