Ruby Blocks, Procs, and Lambdas

Blocks, procs, and lambdas all fall under the umbrella of Ruby closures, which you can learn more about here. Though seemingly similar at first glance, each has its nuanced differences which make it functionally and syntactically different. As a powerful, yet widely misunderstood tool in Ruby, we'll probe the similarities and differences of blocks, procs, and lambdas to become closure pros!

Blocks

We often hear that everything in Ruby is an object; well, blocks aren't. Blocks are simply chunks of code within the syntactical constructs of do/end or {} and cannot work alone; it must always work under a method. A block of code can be passed even if the method doesn't explicitly expect it, as in the example below, but the block will have no effect.

You've probably encountered blocks before when using iterator methods such as .each or .map. But adding the keyword yield in the test_block method signifies a block is needed, will trigger the block, and return the blocks' return value.

You can also pass arguments into blocks as shown below.

Procs

Procs, short for procedures, are similar to reusable blocks, but with a few notable differences:

Below is a basic example of a Proc initialization and call.

Similarly to blocks, procs can also take arguments when called. Blocks and procs seem so similar, why do we need both? Again, procs allows us to save a piece of code in a variable for reuse and allow for multiple blocks of code to be passed.

Lastly, you can convert between block and procs using '&'.

Lambdas

Lambdas are used almost identically as Procs; actually Lambdas are Proc objects to be exact, but with a few significant functional differences:

Below depicts the two varying behaviors of blocks' and procs' 'return.' Another thing to note in lambdas, the 'return' keyword is an immediate trigger to revert to the original calling method, regardless of any code following the keyword.

Resources