From: Robert Klemme Date: 2011-04-13T20:45:00+09:00 Subject: Re: Calling to_enum on a MatchData object On Wed, Apr 13, 2011 at 1:25 PM, Vahagn Hayrapetyan wrote: > 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 = Enumerator.new do |y| >>   (0..9).cycle do |num| >>     y << num >>   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 = Enumerator.new {|y| puts "+"; 5.times {|i| puts "-#{i}"; y << i}} => #:each> irb(main):004:0> e.each {|a| puts "*#{a}"} + -0 *0 -1 *1 -2 *2 -3 *3 -4 *4 => 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 = Enumerator.new {|y| puts "+", y.class; y << 0} => #: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 `
' => # Actually the block of #each is invoked through Enumerator::Yielder#<<. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/