红宝石纤维“死纤维叫”

时间:2014-01-13 04:09:32

标签: ruby fiber

玩弄纤维,我知道我在这里做了些蠢事。但是尝试基于光纤创建一个简单的可枚举类型的东西(使用Enumerable显然是微不足道的)。当我运行以下内容时,在打印出前几次迭代后,我得到一个死光纤错误。有谁知道为什么?

class SumPow
  def initialize(a)
    sum = a
    pow = a
    @fiber = Fiber.new do
      Fiber.yield sum
      pow = pow * a
      sum = sum + pow
    end
  end

  def next
    @fiber.resume
  end

  def each
    loop do
      yield self.next
    end
  end

end

sp = SumPow.new(3)
sp.each do |sum|
  puts sum
end

输出:

3
12
tmp/fiber_enum.rb:96:in `resume': dead fiber called (FiberError)
    from tmp/fiber_enum.rb:96:in `next'
    from tmp/fiber_enum.rb:101:in `block in each'
    from tmp/fiber_enum.rb:100:in `loop'
    from tmp/fiber_enum.rb:100:in `each'
    from tmp/fiber_enum.rb:108:in `<main>'

另一方面,这段代码完全正常:

fib = Fiber.new do
  x, y = 0, 1
  loop do
    Fiber.yield y
    x, y = y, x + y
  end
end
7.times { puts fib.resume }

输出:

1
1
2
3
5
8
13

1 个答案:

答案 0 :(得分:1)

无论光纤状态如何,代码都在调用resume

通过调用Fiber#alive?

检查光纤是否可以恢复
def each
  while @fiber.alive? do
    yield self.next
  end
end

注意您需要require 'fiber'使用alive?方法。


更新符合问题编辑。

原始代码仅产生一次。要无限期地迭代,你需要循环。

def initialize(a)
  sum = a
  pow = a
  @fiber = Fiber.new do
    loop do # <-------------
      Fiber.yield sum
      pow = pow * a
      sum = sum + pow
    end # <-----------------
  end
end