(2012/05/03 8:12), andhapp (Anuj Dutta) wrote:
> Thanks ko1 for your comment. The example doesn't use Fiber#resume on fiber1. It uses Fiber.yield to return to the calling context. However, can you please explain how it should work? I mean, why do you think it's a bug?

You shouldn't use Fiber.yield for "transferred" fiber (in this case, f1).


require 'fiber'

f1 = f2 = f3 = nil

f1 = Fiber.new{
  p:f1
  f2.transfer
  p:f2
}

f2 = Fiber.new{
  p:f2
  Fiber.yield
}

p:a
f1.resume
p:b

In this case, what do you expect?

Output:
ruby 2.0.0dev (2012-05-01 trunk 35505) [i386-mswin32_100]
:a
:f1
:f2
:b

Sequence:
Root      f1          f2
====================================================
p:a
f1.yield
          p:f1
          f2.transfer
                      p:f2
                      Fiber.yield (*1)
p:b
====================================================

Transferred fiber didn't know which fiber should it return to.  So root
fiber was selected.  I think it can cause error (FiberError because
transferred fiber should not use "Fiber.yield").  This is why I think
ruby's bug.

The following code cause an error.

require 'fiber'

fr = Fiber.current
f1 = Fiber.new{
  fr.transfer
}
f1.resume
Fiber.yield

#=>
ruby 2.0.0dev (2012-05-01 trunk 35505) [i386-mswin32_100]
t.rb:8:in `yield': can't yield from root fiber (FiberError)
	from t.rb:8:in `<main>'


Regards,
Koichi

-- 
// SASADA Koichi at atdot dot net