Closures are a powerful feature in Ruby that allow functions to retain access to variables from their enclosing scope. They play a crucial role in functional programming and provide a way to create more flexible and reusable code.
In Ruby, closures are implemented through blocks, Procs, and lambdas. These constructs enable you to create functions that can access and manipulate variables from their surrounding context, even after the original scope has ended.
Let's explore how to create and use closures in Ruby:
Blocks are the simplest form of closures in Ruby. They can access variables from the outer scope:
def counter
count = 0
Proc.new { count += 1 }
end
c = counter
puts c.call # Output: 1
puts c.call # Output: 2
Procs are objects that encapsulate blocks, making them more versatile:
multiplier = Proc.new { |n| n * 3 }
result = [1, 2, 3].map(&multiplier)
puts result.inspect # Output: [3, 6, 9]
Lambdas are similar to Procs but have slight differences in behavior:
greet = ->(name) { "Hello, #{name}!" }
puts greet.call("Ruby") # Output: Hello, Ruby!
Closures in Ruby capture the binding of their surrounding scope. This means they can access and modify variables from the outer scope:
def create_multiplier(factor)
->(x) { x * factor }
end
double = create_multiplier(2)
triple = create_multiplier(3)
puts double.call(5) # Output: 10
puts triple.call(5) # Output: 15
Ruby closures are a fundamental concept that enhances the language's expressiveness and flexibility. By mastering closures, you can write more concise, maintainable, and powerful Ruby code. Practice using blocks, Procs, and lambdas to fully grasp their potential in your Ruby projects.