0%
Reading Settings
Font Size
18px
Line Height
1.5
Letter Spacing
0.01em
Font Family
Table of contents

Ruby Proc, Lambda, and Blocks
Ruby on Rails
Ruby on Rails

In Ruby, there are three powerful constructs that allow for flexible and reusable code: Procs, Lambdas, and Blocks. These constructs play a significant role in making Ruby a highly expressive and dynamic language. In this blog post, we will explore each of them and understand their similarities, differences, and use cases.
Blocks
Blocks are chunks of code enclosed within either curly braces {} or do...end. They are not objects and cannot be stored in variables like Procs and Lambdas. Blocks are primarily used to pass behavior to methods and are commonly seen in iterators and method invocations.
Iterating over an Array
Iterating over an Array
// language: ruby 3.2.2 :001 > [1, 2, 3].each do |num| 3.2.2 :002 > puts num * 2 3.2.2 :003 > end 2 4 6 => [1, 2, 3]
Custom Method with a Block
// language: ruby 3.2.2 :001 > def greet(name) 3.2.2 :002 > puts "Hello, #{name}!" 3.2.2 :003 > yield 3.2.2 :004 > puts "Goodbye, #{name}!" 3.2.2 :005 > end => :greet 3.2.2 :006 > 3.2.2 :007 > greet("John") do 3.2.2 :008 > puts "Have a great day!" 3.2.2 :009 > end Hello, John! Have a great day! Goodbye, John! => nil
Blocks are highly flexible and often used for one-time, ad-hoc behavior that is specific to a particular method invocation.
Procs
Procs, short for procedures, are objects that encapsulate blocks of code and allow them to be stored, passed around, and executed at a later time. They are created using the Proc.new or the proc method.
Define and call the Proc
Define and call the Proc
// language: ruby 3.2.2 :001 > my_proc = Proc.new { |x| puts x * 2 } 3.2.2 :002 > my_proc.call(3) #=> 6 6 => nil
Custom Method with a Proc Parameter
// language: ruby 3.2.2 :001 > def perform_operation(a, b, operation) 3.2.2 :002 > result = operation.call(a, b) 3.2.2 :003 > puts "The result is: #{result}" 3.2.2 :004 > end => :perform_operation 3.2.2 :005 > 3.2.2 :006 > add = Proc.new { |x, y| x + y } 3.2.2 :007 > perform_operation(5, 3, add) The result is: 8 => nil
Passing Proc as a parameter
// language: ruby 3.2.2 :001 > numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 3.2.2 :002 > 3.2.2 :003 > even = Proc.new { |num| num.even? } => #<Proc:0x0000000103d8a0c8 (irb):3> 3.2.2 :004 > even_numbers = numbers.select(&even) => [2, 4, 6, 8, 10]
One significant advantage of Procs is their ability to capture variables from their surrounding context, even after the context is gone. This property is known as closures and allows Procs to maintain access to variables that were in scope when the Proc was defined.
Lambdas
Lambdas are similar to Procs in that they encapsulate blocks of code and can be stored and executed later. However, they have some subtle differences in behavior.
Lambdas are created using the lambda keyword or the -> syntax. They enforce strict argument handling and return behavior.
Define and call the Lambda
Define and call the Lambda
// language: ruby 3.2.2 :001 > my_lambda = lambda { |x| puts x * 2 } 3.2.2 :002 > my_lambda.call(3) 6 => nil
In this example, we define a Lambda that behaves similarly to the Proc. However, if we try to call the Lambda with the wrong number of arguments, an ArgumentError will be raised.
// language: ruby 3.2.2 :003 > my_lambda.call(3, 4) (irb):1:in `block in <top (required)>': wrong number of arguments (given 2, expected 1) (ArgumentError)
Unlike Procs, Lambdas have a stricter interpretation of return statements. When a Lambda encounters a return statement, it only returns from the Lambda itself, whereas a Proc would return from the surrounding context as well.
// language: ruby 3.2.2 :001 > def proc_return 3.2.2 :002 > Proc.new { return "proc return" }.call 3.2.2 :003 > return "proc_return method finished" 3.2.2 :004 > end 3.2.2 :005 > proc_return => "proc return" 3.2.2 :006 > 3.2.2 :007 > def lambda_return 3.2.2 :008 > lambda { return "lamba return" }.call 3.2.2 :009 > return "lambda_return method finished" 3.2.2 :010 > end 3.2.2 :011 > lambda_return => "lambda_return method finished"
Related blogs


How to add a custom Inline Code to Trix editor
Lately, I’ve been improving the writing experience in my Rails app, and something kept bugging me: I wanted a way to add inline code formatting in the Trix editor, just like those snippets you see on blogs and documentation sites.Turns out, Trix does...
Ruby on Rails
Ruby on Rails


I just made a serious mistake with Rails destroy_all
Rails Active Record is convenient and human-readable for interacting with SQL models. But not understanding the generated SQL behind these elegant methods can cause serious data loss that might go unnoticed until it's too late.1. Setting the SceneThi...
Ruby on Rails
Ruby on Rails
