fibers/transferring_no_parens.rb
tests/_examples/fibers/transferring_no_parens.rb in the metorex repository.
# A fiber reached by a transfer from the top level hands what it answered
# back to the top level.
first = Fiber.new { :first }
second = Fiber.new { first.transfer; :second }
p second.transfer
p second.transfer
# One reached by a transfer inside a resumed fiber hands it to that fiber.
finisher = Fiber.new { :finisher }
starter = Fiber.new { Fiber.yield finisher.transfer; :unreached }
p starter.resume
# A fiber waiting in Fiber.yield takes no transfer.
begin
starter.transfer
rescue FiberError => error
p error.message
end
# Transferring to the fiber running now leaves it there.
p Fiber.current.transfer 1, 2
root = Fiber.current
p Fiber.new { root.transfer :back }.transfer
# A dead fiber takes no transfer.
done = Fiber.new { 1 }
done.transfer
begin
done.transfer
rescue FiberError => error
p error.message
end
# A fiber part-way through resuming another takes no transfer.
outer = nil
inner = Fiber.new { outer.transfer }
outer = Fiber.new { inner.resume }
begin
outer.resume
rescue FiberError => error
p error.message
end
begin
Fiber.new { root.transfer }.resume
rescue FiberError => error
p error.message
end
# A fiber made on one thread takes no transfer from another.
here = Fiber.new { 42 }
Thread.new do
begin
here.transfer
rescue FiberError => error
p error.message
end
end.join
p here.transfer
# A thread's own fiber and one it made hand control back and forth.
Thread.new do
helper = Fiber.new { |calling| calling.transfer :from_helper; :helper_done }
p helper.transfer Fiber.current
p helper.transfer
end.join
# A fiber resumed inside another can transfer to the top level, and a
# transfer back to it later finishes both.
low = Fiber.new { answer = root.transfer :up; [answer, :low_done] }
high = Fiber.new { [low.resume, :high_done] }
p high.transfer
p [low.alive?, high.alive?]
begin
high.transfer
rescue FiberError => error
p error.message
end
p low.transfer :down
p [low.alive?, high.alive?]
Output:
:first
:second
:finisher
"attempt to transfer to a yielding fiber"
[1, 2]
:back
"dead fiber called"
"attempt to transfer to a resuming fiber"
"attempt to transfer to a resuming fiber"
"fiber called across threads"
42
:from_helper
:helper_done
:up
[true, true]
"attempt to transfer to a resuming fiber"
[[:down, :low_done], :high_done]
[false, false]