How do I use the Enumerable mixin in my class?

Ruby

Ruby 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbenView Question on Stackoverflow
Solution 1 - RubyMichael KohlView Answer on Stackoverflow
Solution 2 - Ruby3limin4t0rView Answer on Stackoverflow