Differences between [1,2,3].to_enum and [1,2,3].enum_for in Ruby
enumerable, enumeration, ruby
Solution
p [1, 2, 3].to_enum
p [1, 2, 3].enum_for
--output:--
#<Enumerator: [1, 2, 3]:each>
#<Enumerator: [1, 2, 3]:each>
From the docs:
to_enum
Creates a new Enumerator which will enumerate by calling method on obj, passing args if any.
...
enum_for
Creates a new Enumerator which will enumerate by calling method on obj, passing args if any.
ruby is a language that often has method names that are synonyms.
Followup question:
Does the symbol in the command [1,2,3].to_enum(:foo) serve a purpose, other than replacing :each with :foo in the output?
Yes. By default, ruby hooks up the enumerator to the receiver's each() method. Some classes do not have an each() method, for instance String:
str = "hello\world"
e = str.to_enum
puts e.next
--output:--
1.rb:3:in `next': undefined method `each' for "helloworld":String (NoMethodError)
from 1.rb:3:in `<main>
to_enum() allows you to specify the method you would like the enumerator to use:
str = "hello\nworld"
e = str.to_enum(:each_line)
puts e.next
--output:--
hello
Now, suppose you have the array `[1, 2, 3]`, and you want to to create an enumerator for your array. An array has an each() method, but instead of creating an enumerator with each(), which will return each of the elements in the array, then end; you want to create an enumerator that starts over from the beginning of the array once it reaches the end?
e = [1, 2, 3].to_enum(:cycle)
10.times do
puts e.next()
end
--output:--
1
2
3
1
2
3
1
2
3
1
Problem
In Ruby I'm trying to understand between the `to_enum` and `enum_for` methods. Before I my question, I've provided some sample code and two examples to help w/ context. Sample code: ``` # replicates group_by method on Array class class Array def group_by2(&input_block) return self.enum_for(:group_by2) unless block_given? hash = Hash.new {|h, k| h[k] = [] } self.each { |e| hash[ input_block.call(e) ] << e } hash end end ``` Example # 1: ``` irb (main)> puts [1,2,3].group_by2.inspect => #<Enumerator: [1, 2, 3]:group_by2> ``` In example #1: Calling `group_by` on the array `[1,2,3]`, without passing in a block, returns an enumerator generated with the command `self.enum_for(:group_by_2)`. Example #2 ``` irb (main)> puts [1,2,3].to_enum.inspect => #<Enumerator: [1, 2, 3]:each> ``` In example #2, the enumerator is generated by calling the `to_enum` method on the array `[1,2,3]` Question: Do the enumerators generates in examples 1 and 2, behave differently in any way? I can see from the inspected outputs that they show slightly different labels, but I can find any difference in the enumerators' behavior. ``` # Output for example #1 #<Enumerator: [1, 2, 3]:each> # label reads ":each" # Output for example #2 #<Enumerator: [1, 2, 3]:group_by2> # label reads ":group_by2" ```