Still trying to grok GC & continuations

Hello continuation gurus and others!

I still don't understand why I keep having so many non-gc:ed continuations in my code.

Below is some sample code where each coroutine seem intent on hogging 3 continuations each. I don't see why I shouldn't be able to cut that number down to a single continuation each.

Cutting and pasting the code below and running it should give a printout of

continuations-------------------------------------
wait<3>
wait<2>
exit<b>
exit<a>
init
Currently using: 6 continuations

···

--------------------------------------------------

I would prefer to only keep the first 2, but I can't seem to make that happen. *sigh*

/Christoffer

8<----------------------------- ugly test code starts here -----------------------------------

class StateLess
end
class Continuation
   attr_accessor :tag
   def to_s
     "#{tag}"
   end
end

class TestStateLess < StateLess
   attr_reader :value
   def initialize
     @value = ""
     callcc do |continuation|
       continuation.tag = "init"
       @continuation = continuation
       return
     end
     run
   end

   def run(*arg)
     @value += "retry;" while wait(1) !~ /password/
     @value += "passed;"
     wait(2)
     @value +="passed2;"
     wait(3)
   end

   def wait(position)
     @value += "waiting_at_#{position};"
     @continuation = nil
     callcc do |continuation|
       continuation.tag = "wait<#{position}>"
       @continuation = continuation
       @exit.call
     end
   end

   def go(*arg)
     callcc do |exit|
       exit.tag = "exit<#{arg}>"
       @exit = exit
       @continuation.call(*arg)
     end
     @exit = nil
   end

end
include ObjectSpace
def count_cc
   garbage_collect
   i = 0
   puts "continuations-------------------------------------"
   ObjectSpace.each_object(Continuation) {|x| puts x; i += 1 }
   puts "Currently using: " + i.to_s + " continuations"
   puts "--------------------------------------------------"
end

require 'test/unit'
class Tests < Test::Unit::TestCase
   def test_twin
     a = TestStateLess.new
     b = TestStateLess.new
     assert_equal("", a.value)
     a.go('a')
     assert_equal("waiting_at_1;", a.value)
     b.go('b')
     a.go("passvoid")
     assert_equal("waiting_at_1;retry;waiting_at_1;", a.value)
     b.go("password")
     assert_equal("waiting_at_1;passed;waiting_at_2;", b.value)
     a.go("password")
     assert_equal("waiting_at_1;retry;waiting_at_1;passed;waiting_at_2;", a.value)
     b.go("spam")
     assert_equal("waiting_at_1;passed;waiting_at_2;passed2;waiting_at_3;", b.value)
     count_cc
   end
end