- 1_8_6_287
- 1_8_7_72
- 1_8_7_330
- 1_9_1_378 (0)
- 1_9_2_180 (38)
- 1_9_3_125 (15)
- 1_9_3_392 (0)
- 2_1_10 (0)
- 2_2_9 (0)
- 2_4_6 (0)
- 2_5_5 (0)
- 2_6_3 (0)
- What's this?
A class which provides a method `each’ to be used as an Enumerable object.
An enumerator can be created by following methods.
-
Kernel#to_enum
-
Kernel#enum_for
Also, most iteration methods without a block returns an enumerator. For example, Array#map returns an enumerator if a block is not given. The enumerator has the with_index method. So ary.map.with_index works as follows.
p %w[foo bar baz].map.with_index {|w,i| "#{i}:#{w}" } #=> ["0:foo", "1:bar", "2:baz"]
An enumerator object can be used as an external iterator. I.e. Enumerator#next returns the next value of the iterator. Enumerator#next raises StopIteration at end.
e = [1,2,3].each # returns an enumerator object. p e.next #=> 1 p e.next #=> 2 p e.next #=> 3 p e.next #raises StopIteration
An external iterator can be used to implement an internal iterator as follows.
def ext_each(e) while true begin vs = e.next_values rescue StopIteration return $!.result end y = yield(*vs) e.feed y end end o = Object.new def o.each p yield p yield(1) p yield(1, 2) 3 end # use o.each as an internal iterator directly. p o.each {|*x| p x; [:b, *x] } #=> [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 # convert o.each to an external iterator for # implementing an internal iterator. p ext_each(o.to_enum) {|*x| p x; [:b, *x] } #=> [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
Getting the return value from the underlying method of an Enumerator
This is documented in the example code, but easy to miss.
When you get an Enumerator using #to_enum(:method_name, …), you can get all of the yielded values using #next, but not the value that is finally returned.
That value can be retrieved via the #result attribute of the StopIteration exception object that is raised when calling #next after the underlying method has returned.