Ruby
Теория: Блоки как объекты
Блоки — одна из ключевых концепций в Ruby, без которой практически не обходится ни один кусок кода. Они очень похожи на обычные лямбда-функции, но имеют свои особые черты. Для хорошего понимания языка и происходящего в коде нужно понимать, как они устроены. Здесь мы немного копнем вглубь.
С одной стороны, у блоков есть особый синтаксис создания и передачи в функции как особого параметра.
С другой стороны, сам блок — это объект, как и всё остальное в языке.
Его можно как создать независимо от функции, так и использовать. За
блоки в Ruby отвечает класс Proc:
С объектом-блоком можно делать всё то же самое, что и с другими объектами. В этом смысле он ведет себя как анонимная функция в любом языке. Однако, если мы захотим этот объект использовать как блок при передаче в функцию, то ничего не получится:
Хотя мы и имеем дело с блоком, всё же в примере выше он передается в
функцию как обычный объект первым параметром. Но метод map() не
принимает на вход ничего, кроме блока, поэтому код завершается с
ошибкой. Блок, созданный как объект, невозможно напрямую использовать в
методах, ожидающих на вход блоки. Для этого нужен специальный синтаксис:
Амперсанд, добавленный в начале переменной, содержащей блок, передает этот блок в функцию не как параметр, а как блок. Но тут нас ждет сюрприз:
Это поведение не должно вас вводить в заблуждение. Выше мы видим
исключительно особенности синтаксиса. Блок выше не передается как
параметр, это легко увидеть, если посмотреть на определение метода
map(). Он не принимает на вход никаких параметров.

