Callcc problem in Generator

Hey all,

I was playing with the Generator class the other day and decided I
didn't like that you can't break out while iterating through the
generator without first having already taken the time to iterate to
the element after the one you were at when you decided to break out.

The following code shows what I mean. It runs through
test_generator() twice, the first with the current implementation of
Generator, and the second with a new one I whipped up. It shows that
the current implementation takes longer to execute when breaking out
early. Also, outside of performance, I don't like that if I were
reading a stream of data and decided to break out, it would read one
too many lines--kind of an ugly side-effect.

Unfortunately, there's a significant bug in my version that I been
trying to crack all night and I can't figure it out for the life of
me. I want to be able to start iterating, then midway through, call
rewind(), and then start iterating through again. When I do that, it
leaves the stack in an odd place, and when I call each(), it will make
it all the way to the end then get caught in an infinite loop inside
next?().

So I guess my question is, if you create a continuation with callcc()
and then decide never to call that continuation, is there some way to
unwind the stack?

Thanks,
Greg

require 'generator'

def test_generator()
  timeStart = Time.now
  puts "start constructing at #{Time.now - timeStart}"
  gen = Generator.new do |g|
    for num in [1,2,3,4,5]
      sleep(3)
      g.yield(num)
    end
  end
  
  puts "finished constructing at #{Time.now - timeStart}"
  
  puts "getting first element at #{Time.now - timeStart}"
  for num in gen
    puts num
    break if num == 3
    puts "getting next element at #{Time.now - timeStart}"
  end
  puts "done at #{Time.now - timeStart}"
  
  puts "\n\n"
end

puts "Ruby's Generator"
test_generator()

class EndOfGenerator < Exception
end

class Generator
  def initialize(&closure)
    @closure = closure
    return rewind()
  end
  
  def each()
    rewind()
    
    while self.next?()
      yield self.next()
    end
    return self
  end
  
  def rewind()
    @closureEntryPoint = nil
    @currentElement = nil
    @nextElement = nil
    @position = -1
    #self.next?()
    return self
  end
  
  def pos()
    return @position
  end
  
  def current()
    if @currentElement == nil
      begin
        self.next()
        @nextElement = @currentElement
      rescue EndOfGenerator
      end
    end
    
    return @currentElement
  end
  
  def next?()
    return true if @nextElement
    begin
      @nextElement = self.next()
      return true
    rescue EndOfGenerator
      return false
    end
  end
  
  def end?()
    return !self.next?()
  end
  
  def next()
    if @nextElement
      @currentElement = @nextElement
    else
      @currentElement = callcc do |cc|
        @generatorEntryPoint = cc
        if @closureEntryPoint == nil
          @closure.call(self)
          raise EndOfGenerator.new()
        else
          @closureEntryPoint.call()
        end
      end
      @position += 1
    end
    @nextElement = nil
    return @currentElement
  end

  def yield(obj)
    return callcc do |cc|
      @closureEntryPoint = cc
      @generatorEntryPoint.call(obj)
    end
  end
end

puts "Corrected generator"
test_generator()