Fiberをdupする

Ruby1.9のFiberをdupしてみるよー


まずはFiberのインスタンスdupしてみます。

fb = Fiber.new{
  a = 100
  loop {
    a += 1
    Fiber.yield a
  }
}

puts fb.resume
puts fb.resume
puts fb.resume

fb2 = fb.dup
p fb2

puts fb2.resume
puts fb2.resume
puts fb2.resume


結果

$ ruby -v fiber_dup.rb 
ruby 1.9.2dev (2009-04-07 trunk 23147) [i686-linux]
101
102
103
#<Fiber:0x98437cc>
fiber_dup.rb:16:in `resume': uninitialized fiber (FiberError)
	from fiber_dup.rb:16:in `<main>'

Fiberのインスタンスdupできるけど
dupしたインスタンスはresumeすると怒られる(FiberError)


次にFiberのインスタンスインスタンス変数に持ったクラスのインスタンスdupしてみる(ややこし)

class Test
  def initialize
    @fb = Fiber.new{
      a = 100
      loop {
        a += 1
        Fiber.yield a
      }
    }
  end
  def read
    @fb.resume
  end
end

t = Test.new

puts t.read
puts t.read
puts t.read

t2 = t.dup
puts t2.read
puts t2.read
puts t2.read


結果

$ ruby -v fiber_dup.rb 
ruby 1.9.2dev (2009-04-07 trunk 23147) [i686-linux]
101
102
103
104
105
106


おぉ、怒られずに動作する!
しかも、ちゃんとaの値が継続していますね。


前者が動かなくて後者が動かないのはなんでだろう...
自分的には後者が動けば問題無いのですけど。


追記:
id:nagachikaさんにコメントいただきました。
後者の動作はtとt2のfiberが同一になっているだけでした。。うへぇ。