Generators via Lazy Evaluation

Hello again Friends,

Welcome to another installment of Danno creates strange things that
nobody asked for and puts them on the mailing list.

Today's session is about creating sequence generators using Lazy
Evaluation of closures as opposed to the regular method involving
continuations and closures.

In terms of performance, I think it runs a smidge faster than
Generator.rb in the Standard Library, however it does snap the Stack
in half like a twig because of all of the recursive calls.

Actually, I really don't have much to say about it except I'm curious
what sorts of stuff I should add to the LazyGenerator module presented
herein to make it more useful. I think making it capable of returning
array slices would be a good start, but I'm not sure where else to
go. Would it make sense to have it support Enumerable for values
computed thus far? Or should I create a set of functions similar to
Enumerable, but all supporting the specification of a maximum depth?

class Lazy

  instance_methods.each { |m| undef_method m unless m =~ /^__/ }

  def initialize(switch = :one_eval, &block)
    @code_block = block
    @mode = switch
  end

  def method_missing(symbol, *args)
    if @mode == :one_eval
      @real_obj ||= @code_block.call
      @real_obj.__send__(symbol, *args)
    else
      @code_block.call().__send__(symbol, *args)
    end
  end
end

def lazy(switch = :one_eval, &block)
  Lazy.new(switch, &block)
end

module LazyGenerator
  
  def initialize
    @arr = []
    @arr[0] = lazy {self.next}
  end
  
  def[] n
    if @arr[n].nil?
      self[n-1].object_id
      return @arr[n]
    else
      return @arr[n]
    end
  end
  
  def inspect
    return "LazyGenerator"
  end
  
end

class PositiveInts
  
  include LazyGenerator
  
  def next(prev = 0, index = 0)
    @arr[index] = prev+1
    @arr[index+1] = lazy {self.next(@arr[index], index+1)}
    return @arr[index]
  end
end

class Fibs

  include LazyGenerator
  
  def next(index = 0)
    if index == 0
      @arr[index]= 0
    elsif index == 1
      @arr[index] = 1
    else
      @arr[index] = @arr[index-1] + @arr[index-2]
    end
    
    @arr[index+1] = lazy {self.next(index+1)}
    return @arr[index]
  end
end

As usual, feel free to berate me for wasting your time on
inconsequential matters.

···

--
-Dan Nugent