Ruby Fibers at Depth
A fiber is a block of code that can pause in the middle and resume later. Fibers hand values out as they pause and take values in as they resume.
A fiber pauses and resumes
The first resume runs the fiber up to its yield and stops there. The second resume picks up right after the yield.
fiber = Fiber.new do
puts "inside the fiber"
Fiber.yield
puts "back inside"
end
puts "before resume"
fiber.resume
puts "between resumes"
fiber.resumeValues cross in both directions
resume hands 21 in and the yield hands 42 back out. The next resume hands 100 in, and the fiber prints it.
fiber = Fiber.new do |start|
doubled = Fiber.yield start * 2
puts doubled
end
answer = fiber.resume(21)
puts answer
fiber.resume(100)An enumerator yields lazily
The counter block could run forever, yet take asks for only a few values. Each take starts the count again from one.
counter = Enumerator.new do |yielder|
number = 1
loop do
yielder << number
number += 1
end
end
p counter.take(2).to_a
p counter.take(4).to_aA finished fiber answers its last value
The first resume stops at the yield and returns its value. The second resume runs the fiber out, and its last value comes back.
fiber = Fiber.new do
Fiber.yield "halfway"
"finished"
end
puts fiber.resume
puts fiber.resumeExample
words = Enumerator.new do |yielder|
yielder << "sun"
yielder << "moon"
yielder << "star"
end
p words.take(2).to_a
greeter = Fiber.new do |name|
Fiber.yield "hello #{name}"
"bye #{name}"
end
puts greeter.resume("Ana")
puts greeter.resumeKey points
- Fiber.new builds a fiber that runs only when resume is called on it.
- Fiber.yield pauses the fiber and hands a value back to the caller.
- The next resume restarts the fiber right after the yield and hands a value in.
- An Enumerator runs its block inside a fiber, so values are made one at a time.
- A fiber that runs to its end answers its last value to the final resume.
In this example, the enumerator hands out two words and pauses with the third still unmade. The greeter fiber takes a name in on the first resume, yields its greeting, and answers its closing line on the second resume.
Note
A fiber stays on the same thread, so its pauses are fully predictable.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does Fiber.yield do inside a fiber?