TheUpperCode | Розробка сайту | Ruby on Rails
  • Головна
  • Послуги
  • Про нас
  • Співпраця
  • Проекти
  • Блог
  • Контакти
  • en
    • en
Назад
logo

Дизайн

UX/UI дизайн

Web дизайн

Продуктовий дизайн

Вебсайт

Розробка

Підтримка

Оновлення

CRM-система

Розробка

Підтримка

Оновлення

Ruby on Rails

Розробка

Підтримка

Оновлення

Автоматизація

Бізнес процеси

Підтримка

Оновлення

News
/
Блоки, процедури та лямбди

Блоки, процедури та лямбди

22 May 2023
Навчання
TheUpperCode | Блоки, процедури та лямбди  | Ruby on Rails

Розуміння блоків 

 

Блоки — це маленькі анонімні функції, які можна передати в методи. Блоки укладено в оператор do / end або в фігурні дужки {}, і вони можуть мати кілька аргументів. Імена аргументів визначаються між двома вертикальними знаками ||, які ще називають трубками(tubes). 

В попередніх уроках ми вже розглядали різні методи, де бачили використання блоків та аргументів в них 

Приклад для блоків в один рядок: 

Приклад для блоків в декілька рядків: 

Блоки корисні, оскільки вони дозволяють зберегти трохи логіки (коду) і використовувати його пізніше. Це щось типу запису даних у файл, порівняння рівності одного елемента іншому або навіть друк повідомлення про помилку.

 

Ключове слово Yield

 

Що означає yield у Ruby? 

yield — це ключове слово Ruby, яке викликає блок, коли ви його використовуєте. 

Це як методи ВИКОРИСТОВУЮТЬ блоки! yield використовується всередині методів для виклику блоку, переданого у цей метод. 

yield - (англ. "поступитися") буквально означає для рубі: як тільки побачиш це слово в методі, виконай блок коду, який передали в метод останнім аргументом і далі продовжуй виконувати код методу в звичайному режимі. 

Приклад: 

Це запускає будь-який блок, який був переданий в print_once, у результаті на екрані буде надруковано «Block is being run» (Блок виконується). 

Ти знав, що yield можна використовувати кілька разів в одну блоці? 

Кожного разу, коли ви викликаєте yield , блок запускатиметься, тому це схоже на повторний виклик того самого методу. 

Приклад:

Ви можете передати будь-яку кількість аргументів для yield, ніби як для методів. 

Потім ці аргументи стають аргументами блоку. У цьому прикладі число. 

 

Виклик методу з yield без блоку 

 

Якщо викликати метод з yield без блоку, то буде помилка. 

Щоб дозволити використання методу як із блоком так і без нього, використовується метод block_given?, який є у Ruby.

 

Неявні блоки проти явних блоків

 

Блоки можуть бути «явними» або «неявними». Явний означає, що ви даєте йому назву у своєму списку параметрів. Ви можете передати явний блок іншому методу або зберегти його у змінній для використання пізніше. 

Приклад: 

Зверніть увагу на параметр &block… Ось як ви визначаєте назву блоку!

 

Що таке лямбда?

 

Lambda (лямбда) - це спосіб визначення блоку та його параметрів за допомогою спеціального синтаксису. Ви можете зберегти цю лямбду у змінній для подальшого використання. Синтаксис для визначення лямбд виглядає так: 

А також ви можете використовувати альтернативний синтаксис: lambda замість

->. 

Суть залишилася та сама, лише трішки синтаксис змінився.

Визначення лямбди не запускатиме код у ньому, так само як визначення методу не запускатиме метод, для цього вам потрібно використовувати метод call.  

Приклад: 

Існують інші способи виклику лямбди, добре знати, що вони існують, однак я рекомендую дотримуватися call для ясності. 

Приклад: 

Лямбда також може приймати аргументи, ось приклад: 

Якщо ви передасте лямбді неправильну кількість аргументів, вона викличе виняток (exception), як і звичайний метод. 

 

Lambdas vs Procs 

 

Proc (процедури) - мають дуже подібну концепцію... Одна з відмінностей полягає в тому, як ви їх створюєте. 

Приклад: 

Спеціального класу Lambda немає. Лямбда – це лише спеціальний об’єкт класу Proc. Якщо ви подивитеся на методи екземпляра з Proc, ви помітите, що існує метод lambda? 

Процедура поводиться інакше, ніж лямбда, особливо коли йдеться про аргументи: 

Ще одна відмінність між proc і lambda полягає в тому, як вони реагують на оператор return. 

Лямбда повернеться нормально, як звичайний метод, а процедура спробує повернутися з поточного контексту. Ось що я маю на увазі: 

Якби процедура була всередині методу, тоді виклик return був би еквівалентним поверненню з цього методу.

Давайте продемонструю в наступному прикладі, що я маю на увазі: 

В цьому прикладі буде виведено Before proc, а після виклику процедури my_proc нам буде повернуто число 2 та вийде з методу call_proc. 

 

Ось короткий список опису того, чим відрізняються процедура і лямбда: 

  • Лямбди визначаються за допомогою -> {}, а процедури — за допомогою Proc.new {}. 
  • Процедури повертаються з поточного методу, тоді як лямбда повертається зі самої себе (лямбди). 
  • Для процедури не важлива правильна кількість аргументів, у той час як лямбди викликають виключення (exception). 

Поглянувши на цей список, ми можемо побачити, що лямбда набагато ближче до звичайного методу, ніж процедури. 

 

«Замикання» 

 

Ruby процедури та лямбди також мають ще один спеціальний атрибут. Коли ви створюєте процедуру, вона має свою область виконання. 

Ця концепція, яку іноді називають замиканням, означає, що процедура матиме з собою такі значення, як локальні змінні та методи з контексту, де вона була визначена.  

Вони містять не фактичні значення, а посилання на них, тому, якщо змінні зміниться після створення процедури, процедура завжди матиме останню версію. 

Прикдад: 

У цьому прикладі ми маємо локальну змінну count, яка має значення 1. 

У нас також є процедура під назвою my_proc і метод call_proc, який запускає (через метод call) будь-яку процедуру або лямбду, передану як аргумент. 

Як ви думаєте, що надрукує ця програма? 

Здавалося б, 500 є найбільш логічним висновком, але через ефект «замикання» буде виведе 1. 

Це відбувається тому, що процедура використовує значення count з місця, де було визначено процедуру, і це поза визначенням методу. 

 

Клас прив'язки

 

Де процедури та лямбди зберігають цю інформацію про область виконання? 

Давайте розповім вам трохи про клас Binding… 

Коли ви створюєте об’єкт Binding за допомогою методу прив’язки, ви створюєте «якір» до цієї точки коду. 

Кожна змінна, метод і клас, визначені на цьому етапі, будуть доступні пізніше через цей об’єкт, навіть якщо ви перебуваєте в зовсім іншій області. 

Приклад: 

foo доступний завдяки прив’язці, навіть якщо ми перебуваємо за межами методу, де його було визначено. 

Якщо ви спробуєте надрукувати foo безпосередньо, ви отримаєте помилку: 

Причина в тому, що foo не було визначено поза методом раніше/попредньо.

Іншими словами, виконання чогось у контексті зв’язувального об’єкта є таким самим, як якщо б цей код був у тому самому місці, де це зв’язування було визначено (пам’ятайте метафору «якоря»). Вам не потрібно безпосередньо використовувати об’єкти прив’язки, але все одно добре знати, що такі штуки існують 🙂

 

Заключення 

 

У цьому дописі ви дізналися, як працюють блоки, відмінності між процедурами та лямбдами, а також дізналися про ефект «замикання», який виникає щоразу, коли ви створюєте блок. 

Тема є досить складна для розуміння, отже потребує практики!

Тому ДЗ на сьогодні: 

  1. Ваше завдання — відсортувати заданий рядок. Кожне слово в рядку міститиме одне число. Це число є позицією слова в результаті. 
  2. Примітка. Числа можуть бути від 1 до 9. Отже, 1 буде першим словом (а не 0). 
  3. Якщо вхідний рядок порожній, поверніть порожній рядок. Слова у вхідному рядку міститимуть лише дійсні послідовні числа. 

Приклад що в нас є і що маємо отримати на виході: 


Лінки на додаткові джерала по сьогоднішньому матеріалу: 

Блоки(blocks) та yield 

Процедруи(Proc) та лямбди(lambda) 

«Чітшіт» на все вище перераховане 


Група в телеграмі: https://t.me/ruby4you

Автор курсу: Шкоропад Даниїл

Хочете приєднатися до нашої мети? Звертайтесь ;)
Зв'язатися
TheUpperCode | Copy our new post about usefull things in WebDevelopment with help Ruby on Rails
Copied
TheUpperCode | Our official Facebook page | Ruby on Rails
TheUpperCode | Our official LinkedIn page | Ruby on Rails
Більше новин
Як підтримувати Ruby on Rails проект в 2025-му році? 8 практичних порад
13 March 2025
TheUpperCode | Як підтримувати Ruby on Rails проект в 2025-му році? 8 практичних порад | Ruby on Rails
How to support a Ruby on Rails project in 2025? 8 practical tips
13 March 2025
TheUpperCode | How to support a Ruby on Rails project in 2025? 8 practical tips | Ruby on Rails
  • Головна
  • Про нас
  • Співпраця
  • Проекти
  • Блог
  • Контакти

TheUpperCode | Website development | Ruby on Rails