
Черт возьми, что за хрень эти свободно плавающие фрагменты кода, смежные с этим #методом, который вызывается (чешет затылок). Хм, я уверен, что должен был видеть что-то подобное раньше .. где-то; ах, но, конечно же, Array#each не имеет смежного кода после вызова метода?

Блоки Ruby можно найти в каждом приложении или скрипте Ruby. Скорее всего, вы использовали блоки Ruby, даже не подозревая об этом — при условии, что вы использовали такие методы, как Array#each.
доказательство 1

Мы углубимся в этот фрагмент кода по мере продвижения в этой статье. Но пока важно понимать, что у нас есть массив из 5 целых чисел: [1, 2, 3, 4, 5]; этот экземпляр класса Array вызывает метод #each; Рядом с методом #each мы находим... звук труб … блок Ruby. Вот и все. Были сделаны! Тем не менее, вы можете продолжить чтение, если хотите — я вас умоляю.
Что такое блоки Ruby?
- Вкратце: блоки Ruby — это анонимные функции, которые вызываются при вызове метода.
- В приведенном выше примере (пример 1) с использованием Array#each соседний блок Ruby принял форму (пример 2):
доказательство 2

- В приведенном выше фрагменте кода обратите внимание на синтаксис блока — это одна из форм выражения блока (обычно используется, когда логика блока занимает несколько строк) — альтернативноблок можно создать с помощью фигурных скобок (например, видно ниже). Оба блока по сути одинаковы.
доказательство 3

- Между «do/end» или «{ }» находится логика блока.
- Ruby полон синтаксического сахара, и блоки Ruby не являются исключением. Блоки Ruby являются частью синтаксиса Ruby — когда синтаксический анализатор Ruby читает блок, он автоматически связывает его с вызываемым методом (#each) в нашем примере выше.
Основной пример
- Вот базовый пример использования блока Ruby.
- Здесь определен метод с именем #pass_a_block. Затем вызывается метод и передается соседний блок. Затем блок выполняется из тела вызываемого метода.
- Обратите внимание, что ключевое слово yield отвечает за выполнение логики блока.
доказательство 4

Как вызывается блок внутри тела метода?
- Хорошо, теперь, когда мы создали метод и передали этому методу блок при вызове, вы можете спросить себя: как блок был выполнен?
- Как упоминалось выше, как только синтаксический анализатор Ruby распознает блок рядом с вызываемым методом, он свяжет этот блок с выполняемым методом.
- Если в теле выполняемого метода есть ключевое слово yield, yield будет действовать как связующее звено и выполнять блок в контексте метода.
- Короче говоря, при выполнении метода ключевое слово yield заменяется логикой связанного блока.
- По сути, вы предоставляете изменяемый код определенному методу — примерно как в приведенном ниже примере, хотя исходный метод не переопределяется.
доказательство 5

- Примечание. Блок всегда можно передать или привязать к методу, хотя, если ключевое слово yield отсутствует в теле соответствующего метода, блок не будет использоваться (см. ниже).
приложение 6

Возвращаемое значение блока
- Внутри блока ключевое слово возврата явно не используется.
- Возвращаемое значение блока является неявным.
- Последняя строка выполнения внутри блока будет возвращаемым значением.
- Если yield является последней строкой, выполняемой в методе, то возвращаемое значение метода будет возвращаемым значением блока.
- Вы также можете присвоить возвращаемое значение yield (или выполнение блока) переменной и в дальнейшем использовать его в последовательной логике в теле вашего метода (см. ниже).
приложение 6

Блоки и их аргументы
Я намеренно опустил эту тему в нескольких последних разделах, чтобы предоставить знакомый пример (Array#each).
Но время пришло — спорить бесполезно 😉.
- Блоки могут быть записаны либо с включением аргументов или без них. Лучше всего это продемонстрировать на примере (см. ниже).
доказательство 7

доказательство 8

- Блокам можно передавать несколько аргументов.
- Ожидаемые аргументы блока определяются в списке, разделенном запятыми, между набором каналов т.е.
|argument_one, argument_two| - Аргументы, переданные для получения , т.е.
yield(my_block_arg)соответствуют аргументам блока, определенным между его каналами, т.е.|my_block_arg| - Давайте объединим часть полученной информации и напишем собственный метод Array#each.
доказательство 9

- Сначала мы открываем класс Array и переопределяем метод Ruby Array#each нашим собственным упрощенным методом #each.
- В этом методе мы просто создаем индексную переменную, объявленную как
i. - Затем мы перебираем
self(экземпляр Array). - В цикле мы вызываем yield — последовательно передавая каждый элемент по мере того, как мы перебираем экземпляр Array.
- Когда мы вызываем наш метод #each для экземпляра Array т.е.
[1, 2, 3, 4, 5].each— мы передаем в #each блок, который принимает аргумент (который будет элементом массива, переданным для yield из тела метода). - Оттуда мы просто выводим каждый элемент массива * 10 .
Лексическое окружение блока
- Блоки имеют доступ ко всем переменным из среды, в которой они определены (см. ниже).
приложение 10

Неявные блоки и доходность
- Во всех наших примерах мы передаем блоки методам неявно, т.е. никогда в наших методах мы явно не определяли наш метод для ожидания блока.
- Это связано с тем, что yield является специальным ключевым словом Ruby, оно находит и вызывает блок, который был передан методу.
- Мы можем явно передавать блоки методам — ну вроде того. Я расскажу об этом в одном из будущих руководств — или не стесняйтесь продолжить исследование блоков и процессов, если вы просто не можете ждать.
Сделать «доходность» необязательным в наших методах
- Ключевое слово yield будет искать и выполнять логику блоков И если yield присутствует в теле метода — и этот метод вызывается без блока, вам лучше в это поверить.. урожай будет жаловаться.
- Чтобы предотвратить ошибку, вы можете написать метод для вызова yield только в том случае, если метод вызывается с блоком (см. ниже).
приложение 11

Явные блоки и процедуры
- Вот краткий обзор для тех, кто интересуется методами, вызываемыми с явными блоками:

- Я углублюсь в предмет Procs в следующем уроке.
примечание: если вы вызываете метод без круглых скобок, вы столкнетесь со странным поведением, если используете синтаксис блока ‘{ }’; поскольку блок будет привязан к последнему аргументу, противоположному вызываемому методу. Менее важные — и почти нет необходимости упоминать об этом в данный момент. Не стесняйтесь игнорировать этот пункт.
Спасибо, что нашли время прочитать мою статью! Я Full Stack Developer из Торонто, Канада🇨🇦 . В настоящее время я работаю в Swift Medical, ведущем приложении MedTech.