1

In Ruby, is there a functional difference between these two Enumerators?

irb> enum_map = [1,2,3].map
=> #<Enumerator: [1, 2, 3]:map> # ends with "map>"

irb> enum_group_by = [1,2,3].group_by
=> #<Enumerator: [1, 2, 3]:group_by> # ends with "group_by>"

irb> enum_map.methods == enum_group_by.methods
=> true # they have the same methods

What can #<Enumerator: [1, 2, 3]:map> do that <Enumerator: [1, 2, 3]:group_by> can't do, and vice versa?

Thanks!

popedotninja
  • 1,170
  • 1
  • 12
  • 23

2 Answers2

3

From the documentation of group_by:

Groups the collection by result of the block. Returns a hash where the keys are the evaluated result from the block and the values are arrays of elements in the collection that correspond to the key.

If no block is given an enumerator is returned.

(1..6).group_by { |i| i%3 }   #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}

From the documentation of map:

Returns a new array with the results of running block once for every element in enum.

If no block is given, an enumerator is returned instead.

(1..4).map { |i| i*i }      #=> [1, 4, 9, 16]
(1..4).collect { "cat"  }   #=> ["cat", "cat", "cat", "cat"]

As you can see, each does something different, which serves a different purpose. Concluding that two APIs are the same because they expose the same interface seems to miss the entire purpose of Object Oriented Programming - different services are supposed to expose the same interface to enable polymorphism.

Community
  • 1
  • 1
Uri Agassi
  • 36,848
  • 14
  • 76
  • 93
  • Thank you sir. I should have been more specific. Earlier today, I noticed that `[1,2,3].group_by` (without a block) returns an enumerator. Then I noticed `[1,2,3].map` (without a block) also returns an enumerator. Maybe a better questions to ask is this => What's can I do with the enumerator returned by `[1,2,3].enum_for(:map)` that I can't do with the one returned by `[1,2,3].to_enum`. – popedotninja May 24 '14 at 07:28
  • @amorphid - have you looked at the documentation: http://www.ruby-doc.org/core-2.1.1/Enumerator.html? – Uri Agassi May 24 '14 at 07:33
  • @amorphid It's a fundamental mistake to expect different instances of a class would be equal. Also comparison `enum_map.methods == enum_group_by.methods` only compares objects method *names* not their implementation or even code. – David Unric May 24 '14 at 12:56
2

There's a difference in what they do, but fundamentally they are both of the same class: Enumerator.

When they're used the values emitted by the enumerator will be different, yet the interface to them is identical.

Two objects of the same class generally have the same methods. It is possible to augment an instance with additional methods, but this is not normally done.

tadman
  • 208,517
  • 23
  • 234
  • 262