Blocks, Procs, and Lambdas in Ruby
Ruby provides powerful tools for working with blocks, procs, and lambdas. These constructs allow you to write flexible and reusable code.
Blocks
Blocks are chunks of code that can be passed to methods. They are enclosed in {}
or do...end
.
def call_block
yield
end
call_block { puts "Hello from the block!" }
Passing Blocks to Methods
You can pass blocks to methods explicitly using the &block
syntax.
def call_block_explicitly(&block)
block.call
end
call_block_explicitly { puts "Hello from the explicit block!" }
Procs
Procs are objects that hold blocks of code. They can be stored in variables and passed around.
my_proc = Proc.new { |x| puts "Proc called with #{x}" }
my_proc.call(10)
Lambdas
Lambdas are similar to procs but enforce argument count. They are created using the ->
syntax.
my_lambda = ->(x) { puts "Lambda called with #{x}" }
my_lambda.call(20)
Differences Between Procs and Lambdas
Procs and lambdas differ in how they handle arguments and the return
keyword.
# Proc example
my_proc = Proc.new { |x, y| puts "Proc: #{x}, #{y}" }
my_proc.call(10) # Proc: 10,
# Lambda example
my_lambda = ->(x, y) { puts "Lambda: #{x}, #{y}" }
# my_lambda.call(10) # This will raise an ArgumentError
my_lambda.call(10, 20) # Lambda: 10, 20
Using Blocks with Iterators
Blocks are commonly used with iterators like each
, map
, and select
.
numbers = [1, 2, 3, 4, 5]
# Using each with a block
numbers.each { |n| puts "Number: #{n}" }
# Using map with a block
squared_numbers = numbers.map { |n| n * n }
puts "Squared Numbers: #{squared_numbers}"
# Using select with a block
even_numbers = numbers.select { |n| n.even? }
puts "Even Numbers: #{even_numbers}"
Closures
Blocks, procs, and lambdas are closures, meaning they capture the surrounding context.
def create_multiplier(factor)
->(x) { x * factor }
end
double = create_multiplier(2)
puts double.call(5) # Output: 10
Next: Ruby on Rails Basics