๐ŸŽ“ A1Learner
๐Ÿ”
0 of 28 lessons completed

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.resume

Values 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_a

A 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.resume

Example

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.resume

Key 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?