Blocks, Procs and Lambdas: Ruby Basics
Understanding the Purpose and Differences of Closures: A Comprehensive Guide to Blocks, Procs, and Lambdas in Ruby
Ruby Blocks, Procs, and Lambdas are all used to create closures, which are functions that can capture and store the context in which they were defined. However, they differ in some important ways.
Blocks
A block is a piece of code that can be passed as an argument to a method. Blocks are enclosed in curly braces {} or do/end. Blocks are not objects themselves, but they can be converted to Proc objects using the “&” symbol. Blocks are executed in the context of the method they are passed to, and they cannot be stored for later use.
Here is an example of a block:
In this example, we define a method named print_names
that takes an array of names as an argument and iterates over each name using the each
method. We pass a block to the each
method that takes a single argument name
and prints a message using string interpolation.
We then call the print_names
method and pass in an array of names, as well as a block that prints a message for each name. When the method iterates over each name in the array, it yields to the block and passes in the current name as an argument. The block then executes its code using the current name, and the output should be:
Note that the block is defined within the method call and is not stored for later use. Blocks are a way to pass a chunk of code to a method and execute it within the context of the method.
Procs
A Proc is a block of code that can be assigned to a variable, passed to a method, or returned from a method. Procs are objects that can be created with the Proc.new method or the lambda method. Procs capture the context in which they were created and can be executed in any context. Procs are similar to blocks, but they can be stored and reused.
Here is an example of a proc:
In this example, we define a Proc named multiply
that takes two arguments and returns their product. We then call the Proc using the call
method and passing in the arguments 3
and 4
. Finally, we print the result, which should be 12
.
Lambdas
A lambda is a special kind of Proc that enforces strict argument checking and return values. When a lambda is created, it behaves like a method with respect to argument checking and return values. Lambdas are created using the lambda keyword or the -> operator. Lambdas are objects that can be stored and reused like Procs, but they have stricter argument checking and return value behavior.
Here is an example of a lambda:
In this example, we define a lambda named subtract
that takes two arguments and returns their difference. We then call the lambda using the call
method and passing in the arguments 10
and 3
. Finally, we print the result, which should be 7
.
Note that lambdas are defined using the lambda
keyword or the ->
operator, but the way they are used is the same as for Procs. The main difference between Procs and lambdas is how they handle arguments and return values. Lambdas behave like methods, whereas Procs are more flexible in their behavior.
In summary, blocks are not objects themselves, but can be converted to Proc objects. Procs are objects that can be created and stored for later use. Lambdas are a special kind of Proc that enforce argument checking and return value behavior.