1

I'm having a hard time figuring out why Enumerable#take never terminates given my enumerator:

require 'continuation'

fib = Enumerator.new do |yielder|
  c, x, y = callcc {|cc| [cc, 0, 1]}
  yielder << x
  c.call c, y, x+y
end

# this works as I'd suspect
1.upto(10) do
  puts fib.next
end

# this works as I'd suspect
fib.take(1)

# this never terminates :(
fib.take(10)

From taking a quick glance at enum.c, it looks like the counter in args[1] is probably getting reset to the initial length requested, causing the iteration to never terminate at line 2019. My understanding is that the stack should be restored when the enumerator's internal fiber yields (at yielder << x), and thus my c.call ... shouldn't be a problem (despite it temporarily setting args[1] back to the original length argument)... but that doesn't seem to be the case.

Can anyone explain why fib.take(n) never terminates for some n > 1? Is there something fundamental about how callcc works that I'm probably missing here?

Note: This is on Ruby 1.9.3. And yes, I realize my use of callcc is sort of silly :).

Charles
  • 6,199
  • 6
  • 50
  • 66

0 Answers0