On Wed, Apr 13, 2011 at 1:25 PM, Vahagn Hayrapetyan <vahagnh / gmail.com> wro=
te:
> 7stud -- wrote in post #991942:
>> Here's how you can use an enumerator to create an infinite array--from
>> which you can print out finite chunks:
>>
>> e =3D Enumerator.new do |y|
>> =A0 (0..9).cycle do |num|
>> =A0 =A0 y << num
>> =A0 end
>> end
>>
>>
>> p e.take(15)
>>
>> --output:--
>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4]
>
> I just tried out (0..9).cycle {|n| puts n} in an irb session and had to
> Ctrl+C it to stop the loop. However when wrapped in a Enumerator like
> your example above, just an Enumerator::Generator object is returned.
> What happens to the infinite loop - does it still crunch the numbers out
> in the background or does it "stop" at some point? I looked at puts
> e.methods.sort
> but they aren't very revealing of what's going on with the loop...

The logic is a bit tricky. :-)  The Enumerator::Generator is just
something which can enumerate something.  There is no infinite loop
until you start iterating that instance via #each or any other method
defined in Enumerable.  Actually the loop is "interrupted" every time
"y << num" is invoked.

Demonstration without infinite loop:

irb(main):003:0> e =3D Enumerator.new {|y| puts "+"; 5.times {|i| puts
"-#{i}"; y << i}}
=3D> #<Enumerator: #<Enumerator::Generator:0x1093d1a8>:each>
irb(main):004:0> e.each {|a| puts "*#{a}"}
+
-0
*0
-1
*1
-2
*2
-3
*3
-4
*4
=3D> 5

You can see how the block from line 4 and the last block in line 3 are
called interleavingly.  Here's another way to look at it:

irb(main):013:0> e =3D Enumerator.new {|y| puts "+", y.class; y << 0}
=3D> #<Enumerator: #<Enumerator::Generator:0x1097b340>:each>
irb(main):014:0> e.each { puts caller(0) }
+
Enumerator::Yielder
(irb):14:in `block in irb_binding'
(irb):13:in `<<'
(irb):13:in `block in irb_binding'
(irb):14:in `each'
(irb):14:in `each'
(irb):14:in `irb_binding'
/opt/lib/ruby/1.9.1/irb/workspace.rb:80:in `eval'
...
/opt/bin/irb19:12:in `<main>'
=3D> #<Enumerator::Yielder:0x10978f14>

Actually the block of #each is invoked through Enumerator::Yielder#<<.

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/