💎Ruby Blocks, Procs, and Lambdas
Untangle Ruby's three callable forms one at a time — blocks, procs, and lambdas — until you can convert between them, predict every return-and-arity gotcha, and end by building a small block-taking DSL of your own.
Phase 1Blocks and the Hidden Contract of Every Ruby Method
Blocks, yield, and Ruby's hidden method contract.
Every Ruby method already accepts a block
6 minEvery Ruby method already accepts a block
`yield` is just a method call with mysterious syntax
6 min`yield` is just a method call with mysterious syntax
Prefix a parameter with `&` to turn a block into an object
7 minPrefix a parameter with `&` to turn a block into an object
A block is syntax; a Proc is a value
7 minA block is syntax; a Proc is a value
Phase 2Converting Between Blocks, Procs, and Lambdas
Convert fluently between blocks, procs, and lambdas.
A lambda is a Proc that takes its arguments seriously
7 minA lambda is a Proc that takes its arguments seriously
Four ways to create a callable, and they're not all equal
6 minFour ways to create a callable, and they're not all equal
Turning a block into a Proc is a one-character operation
7 minTurning a block into a Proc is a one-character operation
You can't unlambda a lambda — only create a fresh Proc
7 minYou can't unlambda a lambda — only create a fresh Proc
`method(:name)` makes any method a first-class value
7 min`method(:name)` makes any method a first-class value
Phase 3Arity, Return, and Closure Gotchas in Production
Navigate arity, return semantics, and closure capture.
Your Proc is about to silently drop half its arguments
8 minYour Proc is about to silently drop half its arguments
A `return` inside a Proc just escaped your entire method
8 minA `return` inside a Proc just escaped your entire method
Your callback captured the variable, not the value
8 minYour callback captured the variable, not the value
Reading a production stack trace with callables in it
8 minReading a production stack trace with callables in it
Phase 4Build a Small Block-Taking DSL
Build a block-taking DSL from scratch.
Ship a tiny config DSL that feels like native Ruby
8 minShip a tiny config DSL that feels like native Ruby
Frequently asked questions
- What's the difference between a proc and a lambda in Ruby?
- This is covered in the “Ruby Blocks, Procs, and Lambdas” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- Why does return behave differently in a proc versus a lambda?
- This is covered in the “Ruby Blocks, Procs, and Lambdas” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- When should I use yield instead of a block argument?
- This is covered in the “Ruby Blocks, Procs, and Lambdas” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- How does &block actually work in a method signature?
- This is covered in the “Ruby Blocks, Procs, and Lambdas” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
- What is a Ruby DSL and how do blocks enable it?
- This is covered in the “Ruby Blocks, Procs, and Lambdas” learning path. Start with daily 5-minute micro-lessons that build from fundamentals to hands-on application.
Related paths
🐳Docker Containers Basics
Build the mental model first, then the commands — from containers vs VMs through images, layers, volumes, and networking to composing a multi-service app.
🧪Property-Based Testing
Go beyond example-based tests — learn to express what your code should always do, then let a framework find the inputs that break it.
🦀Rust's Ownership Model
Build a working mental model of Rust's ownership system — from stack vs heap intuition through borrow checker mastery — so you can read and write Rust without fighting the compiler.
💻Elixir Pattern Matching
Stop reading `=` as assignment and start using it as Elixir's core flow-control tool — through function heads, guards, and `with` — until you can rewrite a tiny command parser without a single `if`.