Search code examples
rubyenumerable

Does `map` use `each` or not?


In Ruby, the Enumerable module mixes into collection classes and relies on the class serving up an each method which yields each item in the collection.

Okay, so if I want to use Enumerable in my own class, I'll just implement each [1]:

class Colors
  include Enumerable

  def each
    yield "red"
    yield "green"
    yield "blue"
  end
end

> c = Colors.new
> c.map { |i| i.reverse }
#=> ["der", "neerg", "eulb"]

That works as expected.

But if I override the each method on an existing class with Enumerable, it doesn't break functions like map. Why not?

class Array
  def each
    puts "Nothing here"
  end
end

> [1,2,3].each {|num| puts num }
#=> "Nothing here"
> [1,2,3].map {|num| num**2 }
#=> [1,4,9]

[1]: from http://www.sitepoint.com/guide-ruby-collections-iii-enumerable-enumerator/


Solution

  • Enumerable's implementation of map does use each, but there's nothing stopping an extending class from overriding it with its own implementation that does not use each.

    In this case Array does provide its own implementation of map for efficiency reasons.