Enumerators
An Enumerator is an object that implements iteration in a controlled fashion.
Instead of looping until some condition is satisfied, the object enumerates values as needed. Execution of the loop is paused until the next value is requested by the owner of the object.
Enumerators make infinite streams of values possible.
Custom enumerators
Section titled “Custom enumerators”Let’s create an Enumerator for Fibonacci numbers.
fibonacci = Enumerator.new do |yielder| a = b = 1 loop do yielder << a a, b = b, a + b endendWe can now use any Enumerable method with fibonacci:
fibonacci.take 10# => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]Existing methods
Section titled “Existing methods”If an iteration method such as each is called without a block, an Enumerator should be returned.
This can be done using the enum_for method:
def each return enum_for :each unless block_given?
yield :x yield :y yield :zendThis enables the programmer to compose Enumerable operations:
each.drop(2).map(&:upcase).first# => :ZRewinding
Section titled “Rewinding”Use rewind to restart the enumerator.
ℕ = Enumerator.new do |yielder| x = 0 loop do yielder << x x += 1 endend
ℕ.next# => 0
ℕ.next# => 1
ℕ.next# => 2
ℕ.rewind
ℕ.next# => 0Parameters
Section titled “Parameters”|Parameter|Details
|---|---|---|---|---|---|---|---|---|---
|yield|Responds to yield, which is aliased as <<. Yielding to this object implements iteration.