All original content is created in Ukrainian. Not all content has been translated yet. Some posts may only be available in Ukrainian.Learn more
This content has been automatically translated from Ukrainian.
In Ruby Proc is an object that stores a piece of code (block) and allows it to be executed later. It's like a "stored block" or a "function in a box".

Example 1: we create Proc

say_hello = Proc.new { puts "Hello!" }
say_hello.call
# => "Hello!"
We created a Proc object that stores the code { puts "Hello!" }. Then they called him through .call.

Example 2: Transfer Proc to method

def run_twice(proc)
  proc.call
  proc.call
end

run_twice(Proc.new { puts "Hi!") })
# => "Hi!"
# => "Hi!"
We passed the block of code as an object and called it several times. This is very convenient when you need to reuse logic.

Proc - why such a name?

It's easier to remember the names of methods when you know what it means. Name Proc in Ruby, it is short for "Procedure" (procedure). In programming languages, since time Lisp i Scheme, 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 of working with blocks of code. He took the idea of procedures from Lisp/Scheme and made them objects - that's how the class came about Proc (procedure object).

What is Lambda?

Lambda - it's Proc too, 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!" }
Well, to prove that lambda is a proc:
say_hi.class
=> Proc

The main difference between Proc and Lambda

1. Lambda checks the number of arguments, and Proc - no.
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 to Proc comes out of the entire method, not just with Proc. In Lambda, return completes only 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 be fulfilled
end

puts test_proc
# => "From Proc"
When Proc calls return, it immediately exits the method in which Proc is created, not just from the block.
return in Lambda completes only the lambda itself
def test_lambda
  l = -> { return "From Lambda" }
  result = l.call
  "After Lambda: #{result}" # this line will be fulfilled
end

puts test_lambda
# => "After Lambda: From Lambda"
Lambda behaves like a normal method: return only completes lambda itself, and the method continues to execute.

& and to_proc

When you transfer an ampersand object to Ruby &, Ruby tries to call on it .to_proc 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 block variable.

This post doesn't have any additions from the author yet.

How arrays work in Ruby: practical examples each, map, select, inject, reduce, filter_map
28 Oct 10:38

How arrays work in Ruby: practical examples each, map, select, inject, reduce, filter_map

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
How self, protected and private (Ruby) works
28 Oct 13:52

How self, protected and private (Ruby) works

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Integer division in Ruby: why 6/4 is 1
28 Oct 14:10

Integer division in Ruby: why 6/4 is 1

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
28 Oct 14:42

How &:to_s works in Ruby and what Symbol#to_proc is

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
What happens if you call [1, 2, 3].map(&Person)
29 Oct 17:54

What happens if you call [1, 2, 3].map(&Person)

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Singleton class (eigenclass) in Ruby: what it is and why it is needed
29 Oct 18:29

Singleton class (eigenclass) in Ruby: what it is and why it is needed

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
==, equal?, eql?, === in Ruby: what is checked and when to use
29 Oct 20:47

==, equal?, eql?, === in Ruby: what is checked and when to use

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Include, Extend, Prepend in Ruby: how they work and what's the difference
29 Oct 21:20

Include, Extend, Prepend in Ruby: how they work and what's the difference

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
module_function in Ruby: When module methods are available as modular and as functions
29 Oct 21:53

module_function in Ruby: When module methods are available as modular and as functions

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
What is memoization in Ruby?
30 Oct 10:17

What is memoization in Ruby?

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska