A game, with real Ruby in your browser
Ruby Fiber Lifecycle: Guess Which Line Runs Next
A fiber is a block of code you can pause and continue. Each level is a short program.
Click the mark line you think runs next,
then say what state a fiber is in. Seven levels, from Fiber.yield
to a fiber killed by its own child.
mark isn't part of Ruby. It's this game's checkpoint:
each mark :label records which fiber is running and the status of every fiber.
A second argument, as in mark :got, x, records that value too.
Press → to go on to the next step or level.
The answers come from Ruby (loading WebAssembly…)
Loading Ruby…
Ruby is loading in your browser. This can take a few seconds.
Fibers
What has run so far
The five states you will see
- created:
Fiber.newhas run, the block has not. Nothing happens until the firstresume. - resumed: the fiber is running right now.
- suspended: the fiber stopped at
Fiber.yieldortransferand can be continued later. - suspended by resuming: the fiber called
resumeon another fiber and waits for it to yield or finish. This is whatFiber#inspectprints. - terminated: the block finished, raised, or was killed. It can't run again.
resume and transfer
resume makes a call chain: the fiber you resume returns to you when it yields or ends.
transfer just jumps. Nobody waits for the fiber you transfer to, so it has to transfer
back by itself, and a fiber in a transfer can't be resumed.
kill
Fiber#kill (Ruby 3.3+) ends a fiber from outside. Its ensure blocks run inside the
fiber, no rescue can stop it, and kill returns only after the fiber is done.
A fiber that never started is just marked terminated. One exception: if the fiber is waiting on a
resume of another fiber, Ruby can't switch into it. kill then raises a
RuntimeError in the fiber being resumed, and the kill happens when control gets back (level 7).
How this page knows the answers
The levels and lessons are written by hand, but the answers are not. When the page loads, every level runs in real Ruby, in your browser, via
ruby.wasm. Each mark records which fiber is
running and what Fiber#inspect says about every fiber the level made. mark is a method the
game adds for this: the level code runs inside a module that defines it, and gets its own Fiber
subclass so the game can find every fiber the level creates. The game replays that
record. The same Ruby also runs in this site's test suite on CRuby, so a level that teaches the wrong thing
fails the build.
Further reading
- Fiber in the Ruby documentation.
- cont.c: CRuby's fiber implementation (
rb_fiber_m_kill,fiber_raise,fiber_switch). - jruby/jruby #10062: a proposed JRuby fix for level 7 (not merged yet).
- SWAR String#tr: another page that runs Ruby in the browser, about JRuby's String#tr fast path (jruby/jruby #10000).
Show the in-browser Ruby source