Fibers & Lazy Evaluation

A Fiber is a block of code you can pause with Fiber.yield and resume with resume , cooperatively passing control and values back and forth between the fiber and its caller.

Learn Fibers & Lazy Evaluation in our free Ruby course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.

Part of the free Ruby course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

In this lesson you'll use fibers to build lazy, on-demand sequences and see how Ruby's Enumerator is powered by them.

What You'll Learn in This Lesson

1️⃣ Pause and Resume with Fibers

Create a fiber with Fiber.new {' '} . Calling resume runs it until it hits Fiber.yield , which pauses it and returns a value to the caller. The next resume picks up right after that yield — local variables and all.

2️⃣ Two-Way Communication

Fibers are coroutines: Fiber.yield x sends x out to the caller, and resume(y) sends y back in, becoming the return value of that yield . The first resume usually just primes the fiber up to its first pause.

3️⃣ Lazy Sequences & the Enumerator Connection

Because a fiber produces one value per resume , it's a natural generator: you can model an infinite stream and only compute as far as you pull. Ruby's Enumerator is built on this exact mechanism — enum.next resumes an internal fiber to produce the next item.

🎯 Your Turn

The fiber should pause after each color. Replace each ___ with the call that pauses the fiber and hands a value to the caller.

Build a fiber-based ID generator that yields zero-padded IDs on demand, and run two independent generators side by side. Run with ruby ids.rb .

📋 Quick Reference — Fibers

Practice quiz

How do you create a Fiber?

  • Fiber.start { ... }
  • Fiber.run { ... }
  • Fiber.new { ... }
  • fiber { ... }

Answer: Fiber.new { ... }. You create a fiber with Fiber.new { ... } and run it with resume.

What pauses a fiber from inside its block?

  • Fiber.yield
  • yield
  • Fiber.pause
  • return

Answer: Fiber.yield. Fiber.yield pauses the fiber and hands control (and a value) back to the caller.

What method continues a paused fiber?

  • fiber.next
  • fiber.call
  • fiber.yield
  • fiber.resume

Answer: fiber.resume. fiber.resume continues from where the fiber last paused.

How is a fiber different from a thread?

  • Fibers run in parallel
  • Fibers are cooperative — they only advance when resumed, with no preemption
  • Threads can't share data
  • Fibers are preemptive

Answer: Fibers are cooperative — they only advance when resumed, with no preemption. A fiber only runs between resume and the next yield; it is cooperative, so there is no preemption or race conditions.

What happens if you resume a fiber that has already finished?

  • It raises FiberError (dead/terminated fiber)
  • It returns nil
  • It restarts from the top
  • It blocks forever

Answer: It raises FiberError (dead/terminated fiber). Resuming a finished fiber raises FiberError about a dead/terminated fiber.

How does a value get INTO a fiber?

  • Through Fiber.yield's argument
  • Via a global variable
  • As the return value of Fiber.yield, via resume(arg)
  • You can't pass values in

Answer: As the return value of Fiber.yield, via resume(arg). resume(arg) sends arg in; it becomes the return value of the Fiber.yield that paused the fiber.

Which Ruby class is built on top of fibers internally?

  • Array
  • Enumerator
  • Hash
  • Proc

Answer: Enumerator. Enumerator uses a fiber internally; enum.next resumes it to produce the next value.

Why does the first resume of a two-way fiber often just 'prime' it?

  • To allocate memory
  • To check for errors
  • To start a thread
  • To run it up to its first yield before you feed values in

Answer: To run it up to its first yield before you feed values in. The first resume runs the fiber to its first pause; later resumes can then send values in.

Can fibers achieve true parallelism on their own?

  • Yes, always
  • No — only one fiber runs at a time
  • Only on multiple cores
  • Only with a mutex

Answer: No — only one fiber runs at a time. Fibers are cooperative and run one at a time; for parallelism you reach for threads.

Inside a Fiber block, using the plain keyword instead of will...

  • Pause the fiber correctly
  • Raise immediately
  • Fail to pause the fiber (it's the block keyword, not the fiber pause)
  • Resume the caller

Answer: Fail to pause the fiber (it's the block keyword, not the fiber pause). Plain yield calls the block; you must use Fiber.yield to actually pause the fiber.