# Лямбда и Proc

В прошлом уроке мы познакомились с такой конструкцией как блок кода, который позволяет нам передать запись похожую на объявление метода в другой метод. В этом мы поговорим как мы можем сохранить метод в переменную не выполняя его.

## Proc

Для того чтобы записать метод в переменную можно воспользоваться `Proc`

```ruby
# мы можем определить сколько угодно параметров
func = Proc.new { |x| x + 1 }
# сокращенная запись
func = proc { |x| x + 1 }

# Пока метод call не будет вызван, код внутри Proc выполняться не будет
puts func.call(1) # = 2
```

## Лямбда

А теперь самое интересное, лямбда - потомок Proc. По функционалу они практически не отличаются друг от друга, лишь с двумя отличиями:

* **Лямбда проверяет количество аргументов, которые в нее передаются, Proc — нет**
* **`return` в лямбде, завершает выполнение кода внутри нее, `return` в проке остановливает выполнение метода**

## Количество аргументов

```ruby
lam = lambda { |x| puts x } # лямбда с одним аргументов
lam.call('Привет!') # => Привет!
lam.call # => ArgumentError: wrong number of arguments (0 for 1)
lam.call('Привет,', 'как', 'дела?') # => ArgumentError: wrong number of arguments (3 for 1)
```

Proc игнорирует это

```ruby
proc = proc { |x| puts x } # прок с одним аргументом
proc.call("Привет!") # => Привет
proc.call # => nil
proc.call('Привет,', 'как', 'дела?') # => Привет,
```

## return

```ruby
def lambda_test
  lam = lambda { return }
  lam.call
  puts 'Лямбда напечатает!'
end

lambda_test # => Лямбда напечатает!
```

```ruby
def proc_test
  proc = Proc.new { return }
  proc.call
  puts 'Прок не напечатает :('
end
proc_test # => nil
```

## резюме

* Proc и лямбда объекты, блоки — нет.
* Блок может существовать только как аргумент функции.
* В функцию можно передать только один блок.
* Лямбды проверяют количество аргументов, `Proc` — нет.
* Проки прерывают выполнение функции при вызове `return`, лямбды — нет.
