1

Enumerable#take鉴于我的枚举器,我很难弄清楚为什么永远不会终止:

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)

快速浏览一下enum.c,看起来args[1]中的计数器可能正在重置为请求的初始长度,导致迭代永远不会在第2019行终止。我的理解是,当枚举器的内部光纤产生 (at yielder << x) 时,应该恢复堆栈,因此我c.call ...不应该成为问题(尽管它暂时设置args[1]回原始长度参数)......但这似乎不是就是这样。

谁能解释为什么fib.take(n)永远不会因某些 n > 1 而终止?callcc关于我可能在这里遗漏的工作原理,是否有一些基本的东西?

注意:这是在 Ruby 1.9.3 上。是的,我意识到我的使用callcc有点愚蠢:)。

4

0 回答 0