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
有点愚蠢:)。