2014-01-13 107 views
1

玩光纖,我知道我在這裏做一些愚蠢的事情。但試圖創建一個基於纖維的簡單枚舉類型的東西(使用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

的代碼調用resume不管狀態的纖維呃。

檢查是否纖維可以通過調用Fiber#alive?

def each 
    while @fiber.alive? do 
    yield self.next 
    end 
end 

注意你需要做require 'fiber'使用alive?方法恢復。


UPDATE accoridng的問題編輯。

原始代碼只產生一次。要無限循環,需要循環。

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 
+0

對不起,我應該更清楚,如果我想無限期地使用光纖在這裏迭代怎麼辦? – rainkinz

+0

@rainkinz,問題中的代碼只產生一次:'Fiber.new do ... end'。 – falsetru

+0

@rainkinz,我更新了答案。 – falsetru