Continuation Confusion

Hello,
I was playing around with continuations by studying the generator code in Hal Fulton's Ruby Way book. I decided to re-implement the code to test my understanding. I decided to add the ability to backup the generator and started to get "weird" results. I started to pass the intermediate values on the stack and everything works. But, I would like to understand better why. Can anyone help me? Thanks in advance! Here's my code with comments and tests:

#playing with continuations
#inspired by Generator code in Hal Fulton's book
#I read it and then tried to recreate it to test my understanding
#I add the ability to "backup" the generator. I've added tests as well.

···

#
#I have to pass the locals on the stack to get it to work correctly? Why is this?
#Is there something I am missing? I did use one less continuation, but it's
#just the continuation to continue the loop of the generator.

require 'test/unit'

class Generator
  attr_accessor :currentContext, :contextHistory
  def initialize()
  self.currentContext=nil
  self.reset
  end

  def next
    callcc do |here|
      self.currentContext=here
      if self.contextHistory.empty?
        generatorLoop
      else
        self.contextHistory.last.call
    end
    end
  end

  def backup
    self.contextHistory.pop
  end

  def answer(value, *args)
    callcc do |cont|
      self.contextHistory.push(cont)
      self.currentContext.call(value)
    end
    args
  end

  def reset()
    self.contextHistory=[]
  end
end

class Fibonacci < Generator
  def generatorLoop
    previous, current=0,1
    loop do
      #I pass the previous and current local variables as arguments just so they are returned
      #If I don't pass them, weird things happen which makes me think Ruby
      #continuations only save part of the state or treats closures special on the
      #stack. The variables are local to the method and not the closure. But, I still
      #think the method's local state should be saved on the stack as well. Am I missing
      #something?

      #works
      previous, current = answer(current, previous, current)

      #doesn't work, but I think it should, what am I missing?
      #answer(current)
      previous, current = current, previous + current
    end
  end
end

class TestFibonacci < Test::Unit::TestCase
  attr_accessor :to_test
  def setup
    self.to_test=Fibonacci.new
  end
  def teardown
    self.to_test=nil
  end
  def test_next
    assert_equal(1, self.to_test.next)
    assert_equal(2, self.to_test.next)
    assert_equal(3, self.to_test.next)
    assert_equal(5, self.to_test.next)
    assert_equal(8, self.to_test.next)
  end

  def test_back
    (1..6).each { self.to_test.next }
    assert_equal(13, self.to_test.next)
    self.to_test.backup
    assert_equal(13, self.to_test.next)
    self.to_test.backup
    assert_equal(8, self.to_test.next)
    assert_equal(13, self.to_test.next)
    assert_equal(21, self.to_test.next)
  end

end
--
Blaine Buxton, Mad Scientist In Training
My Amps: Smalltalk, Lisp, and Ruby
http://www.blainebuxton.com

_________________________________________________________________
Is your PC infected? Get a FREE online computer virus scan from McAfee® Security. http://clinic.mcafee.com/clinic/ibuy/campaign.asp?cid=3963

Blaine Buxton schrieb:

But, I still think the method's local state should be saved on the
stack as well. Am I missing something?

Hi Blaine,

if you look at this small example, you see that local variables are indeed *not* saved by continuations:

   v = 1
   c = callcc { |cc| cc }
   puts( v, c )
   if Continuation === c
     v = 2
     c.call( 5 )
   end

Output:

   1
   #<Continuation:0x2a6b738>
   2
   5

Feel free to ask if you need more help.

Regards,
Pit