On Oct 3, 2009, at 6:50 AM, Shot (Piotr Szotkowski) wrote:

> Roger Pack:
>
>>> What is the sanest way to backport the following example so that it
>>> works more-or-less in the same way under Ruby 1.8.7 as it does under
>>> Ruby 1.9?
>
>>> def multiplier param
>>>  Enumerator.new do |yielder|
>
>> This might help:
>
>> http://talklikeaduck.denhaven2.com/2006/10/15/enumeration-improvement-in-ruby-1-9
>> http://stackoverflow.com/questions/1436037/how-do-enumerators-work-in-ruby-1-9-1/1481303#1481303
>> http://anthonylewis.com/2007/11/09/ruby-generators
>
> Hm. I read these and given that it lacks Fibers can√’ figure
> out a way to come up with a simple lazy enumerator in Ruby 1.8. :|
> What am I missing?

   #!/usr/bin/env ruby -wKU

   require "generator"

   fib = Generator.new do |g|
     g.yield(n2 = 0)
     g.yield(n1 = 1)
     loop do
       n2, n1 = n1, n2 + n1
       g.yield(n1)
     end
   end

   p Array.new(10) { fib.next }

Or with a closure:

   #!/usr/bin/env ruby -wKU

   def fibonacci
     n2 = n1 = nil
     lambda {
       if n2.nil?
         n2 = 0
       elsif n1.nil?
         n1 = 1
       else
         n2, n1 = n1, n2 + n1
         n1
       end
     }
   end

   fib = fibonacci
   p Array.new(10) { fib.call }

Or with an object:

   #!/usr/bin/env ruby -wKU

   class Fibonacci
     def initialize
       @sequence = [ ]
     end

     def next
       if @sequence.size < 2
         @sequence << @sequence.size
       else
         @sequence << @sequence[-2] + @sequence[-1]
         @sequence.unshift
       end
       @sequence[-1]
     end
   end

   fib = Fibonacci.new
   p Array.new(10) { fib.next }