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 not been translated yet.We're showing the original Ukrainian content below.
У Ruby Proc - це об’єкт, який зберігає шматок коду (блок) і дозволяє виконувати його пізніше. Це як "збережений блок" або "функція в коробці".

Приклад 1: створюємо Proc

say_hello = Proc.new { puts "Hello!" }
say_hello.call
# => "Hello!"
Ми створили об’єкт Proc, який зберігає код { puts "Hello!" }. Потім викликали його через .call.

Приклад 2: передаємо Proc у метод

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

run_twice(Proc.new { puts "Hi!" })
# => "Hi!"
# => "Hi!"
Ми передали блок коду як об’єкт і викликали його кілька разів. Це дуже зручно, коли потрібно повторно використовувати логіку.

Proc - чому така назва?

Легше запам'ятовувати назви методів, коли знаєш що воно означає. Назва Proc у Ruby - це скорочення від "Procedure" (процедура). У мовах програмування, ще з часів Lisp і Scheme, термін procedure означав "шматок коду, який можна виконати пізніше" - тобто функцію, яку можна передати як аргумент або викликати.
Коли Мацумото (Matz), творець Ruby, проєктував мову, він хотів, щоб Ruby мав простий і гнучкий спосіб роботи з блоками коду. Він узяв ідею процедур із Lisp/Scheme і зробив їх об’єктами - так з’явився клас Proc (procedure object).

Що таке Lambda?

Lambda - це теж Proc, але з деякими відмінностями. Її можна створити кількома способами:
-> { }
say_hi = -> { puts "Hi!" }
say_hi.call
# => "Hi!"
та lambda {}
say_hello = lambda { puts "Hello!" }
Ну а щоб довести, що лямбда це прок:
say_hi.class
=> Proc

Основна різниця між Proc і Lambda

1. Lambda перевіряє кількість аргументів, а Proc - ні.
p1 = Proc.new { |a, b| puts a, b }
l1 = ->(a, b) { puts a, b }

p1.call(1)
# => 1
# => nil   (другий аргумент просто nil)

l1.call(1)
# => ArgumentError: wrong number of arguments
2. return у Proc виходить із всього методу, а не лише з Proc. У Lambda return завершує тільки саму лямбду.
І розглянемо приклади
def test_proc
  p = Proc.new { return "From Proc" }
  p.call
  "After Proc"  # цей рядок не виконається
end

puts test_proc
# => "From Proc"
Коли Proc викликає return, він одразу виходить із методу, у якому створений Proc, а не лише з блоку.
return у Lambda завершує тільки саму лямбду
def test_lambda
  l = -> { return "From Lambda" }
  result = l.call
  "After Lambda: #{result}"  # цей рядок виконається
end

puts test_lambda
# => "After Lambda: From Lambda"
Лямбда поводиться як звичайний метод: return завершує лише саму лямбду, а метод продовжує виконання далі.

& і to_proc

Коли ви передаєте у Ruby об’єкт із амперсандом &, Ruby робить спробу викликати на ньому .to_proc і використовує отриманий Proc як блок.
def run(&block)
  block.call
end

run { puts "Works!" }
# => "Works!"
Тут Ruby автоматично викликав .to_proc для нашого блоку { ... } і передав його в змінну block.

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

Як працюють масиви в Ruby: практичні приклади each, map, select, inject, reduce, filter_map
28 Oct 10:38

Як працюють масиви в Ruby: практичні приклади each, map, select, inject, reduce, filter_map

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Як працює self, protected і private (Ruby)
28 Oct 13:52

Як працює self, protected і private (Ruby)

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Цілочисельне ділення у Ruby: чому 6 / 4 дорівнює 1
28 Oct 14:10

Цілочисельне ділення у Ruby: чому 6 / 4 дорівнює 1

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

Як працює &:to_s у Ruby і що таке Symbol#to_proc

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Що відбувається, якщо викликати [1, 2, 3].map(&Person)
29 Oct 17:54

Що відбувається, якщо викликати [1, 2, 3].map(&Person)

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Singleton class (eigenclass) у Ruby: що це і навіщо потрібно
29 Oct 18:29

Singleton class (eigenclass) у Ruby: що це і навіщо потрібно

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
==, equal?, eql?, === у Ruby: що перевіряють і коли використовувати
29 Oct 20:47

==, equal?, eql?, === у Ruby: що перевіряють і коли використовувати

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Include, Extend, Prepend у Ruby: як вони працюють і в чому різниця
29 Oct 21:20

Include, Extend, Prepend у Ruby: як вони працюють і в чому різниця

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
module_function у Ruby: коли методи модуля доступні як модульні та як функції
29 Oct 21:53

module_function у Ruby: коли методи модуля доступні як модульні та як функції

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Що таке memoization в Ruby?
30 Oct 10:17

Що таке memoization в Ruby?

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