Table of contentsClick link to navigate to the desired location
This content has been automatically translated from Ukrainian.
In Ruby, Proc is an object that stores a piece of code (block) and allows you to execute it later. It's like a "saved block" or "function in a box."
Example 1: creating a Proc
say_hello = Proc.new { puts "Hello!" }
say_hello.call
# => "Hello!"
We created a Proc object that stores the code { puts "Hello!" }. Then we called it using .call.
Example 2: passing a Proc to a method
def run_twice(proc)
proc.call
proc.call
end
run_twice(Proc.new { puts "Hi!" })
# => "Hi!"
# => "Hi!"
We passed a block of code as an object and called it several times. This is very convenient when you need to reuse logic.
Proc - why this name?
It's easier to remember method names when you know what they mean. The name Proc in Ruby is short for "Procedure". In programming languages, since the days of Lisp and Scheme, the term procedure meant "a piece of code that can be executed later" - that is, a function that can be passed as an argument or called.
When Matsumoto (Matz), the creator of Ruby, designed the language, he wanted Ruby to have a simple and flexible way to work with blocks of code. He took the idea of procedures from Lisp/Scheme and made them objects - thus the Proc class (procedure object) was born.
What is a Lambda?
Lambda is also a Proc, but with some differences. It can be created in several ways:
-> { }
say_hi = -> { puts "Hi!" }
say_hi.call
# => "Hi!"
and lambda {}
say_hello = lambda { puts "Hello!" }
And to prove that a lambda is a proc:
say_hi.class => Proc
The main difference between Proc and Lambda
1. Lambda checks the number of arguments, while Proc does not.
p1 = Proc.new { |a, b| puts a, b }
l1 = ->(a, b) { puts a, b }
p1.call(1)
# => 1
# => nil (the second argument is simply nil)
l1.call(1)
# => ArgumentError: wrong number of arguments
2. return in Proc exits from the entire method, not just from the Proc. In Lambda, return only exits the lambda itself.
And let's consider examples
def test_proc
p = Proc.new { return "From Proc" }
p.call
"After Proc" # this line will not execute
end
puts test_proc
# => "From Proc"
When Proc calls return, it immediately exits from the method in which the Proc was created, not just from the block.
return in Lambda only exits the lambda itself
def test_lambda
l = -> { return "From Lambda" }
result = l.call
"After Lambda: #{result}" # this line will execute
end
puts test_lambda
# => "After Lambda: From Lambda"
A lambda behaves like a regular method: return only exits the lambda itself, and the method continues execution.
& and to_proc
When you pass an object with an ampersand & in Ruby, Ruby attempts to call .to_proc on it and uses the resulting Proc as a block.
def run(&block)
block.call
end
run { puts "Works!" }
# => "Works!"
Here, Ruby automatically called .to_proc for our block { ... } and passed it to the variable block.
This post doesn't have any additions from the author yet.