From: Robert Klemme Date: 2011-05-18T23:31:21+09:00 Subject: Re: Making fibers enumerable On Wed, May 18, 2011 at 2:14 PM, Peter Zotov wrote: > On Wed, 18 May 2011 20:12:43 +0900, Robert Klemme wrote: >> >> How would your example look if there was another generation that you >> wanted to do concurrently?  Because for the single threaded generator >> case there is already a tool: Enumerator.new.  The example in the >> documentation even uses Fibonacci Numbers as example. :-) >> >> http://www.ruby-doc.org/core/classes/Enumerator.html#M000299 >> >> fib_gen = Enumerator.new { |y| >>  a = b = 1 >>  loop { >>    y << a >>    a, b = b, a + b >>  } >> } >> >> Now you can do exactly the same as you did with your example >> >> # Find the fibonacci number greater than 1000 >> fib_gen.find {|x| x > 1000 } >> # take first 10 fibonacci numbers >> fib_gen.take 10 >> # take_while numbers are smaller than 1000 >> fib_gen.take_while {|x| x < 1000 } >> >> For this Fiber would be the wrong tool. > > The Enumerator.new uses Fibers internally. Check enumerator.c in the > sources; That's an implementation detail of Enumerator. The point is that the primary purpose of Fiber is to be able to build concurrency without preemption but with manual control over when one task yields to another task. Enumerator.new on the other hand is a tool for generation of sequences of items which is precisely what the Fibonacci example is all about. There is no concurrency. > besides that, how would you achieve the needed effect without coroutines? class X include Enumerable Callback = Struct.new :code do def <<(x) code[x] self end end def initialize(&code) @code = code end def each(&b) cb = Callback.new b @code[cb] self end end fib_gen = X.new { |y| a = b = 1 loop { y << a a, b = b, a + b } } # Find the fibonacci number greater than 1000 p fib_gen.find {|x| x > 1000 } # take first 10 fibonacci numbers p fib_gen.take 10 # take_while numbers are smaller than 1000 p fib_gen.take_while {|x| x < 1000 } Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/