Розгляньмо наш новий застосунок глибше. Зверніть увагу на перші рядки,
які починаються з решітки (#). У Ruby все, що знаходиться в рядку після
решітки, є коментарем і ігнорується інтерпретатором. Перший рядок файлу —
особливий випадок і під Unix-подібними ОС повідомляє shell, як запускати
файл. Решта коментарів потрібна лише для ясності.

Наш метод `say_hi` став трохи складнішим:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># Say hi to everybody</span>
<span class="k">def</span> <span class="nf">say_hi</span>
  <span class="k">if</span> <span class="vi">@names</span><span class="p">.</span><span class="nf">nil?</span>
    <span class="nb">puts</span> <span class="s2">"..."</span>
  <span class="k">elsif</span> <span class="vi">@names</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"each"</span><span class="p">)</span>
    <span class="c1"># @names is a list of some kind, iterate!</span>
    <span class="vi">@names</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="nb">name</span><span class="o">|</span>
      <span class="nb">puts</span> <span class="s2">"Hello </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">!"</span>
    <span class="k">end</span>
  <span class="k">else</span>
    <span class="nb">puts</span> <span class="s2">"Hello </span><span class="si">#{</span><span class="vi">@names</span><span class="si">}</span><span class="s2">!"</span>
  <span class="k">end</span>
<span class="k">end</span></code></pre></figure>

Тепер він дивиться на змінну екземпляра `@names`, щоб приймати рішення.
Якщо вона дорівнює nil, він просто виводить три крапки. Немає сенсу
вітатися з ніким, правда?

## Перебір і цикли — тобто ітерація

Якщо об’єкт `@names` відповідає на `each`, це означає, що його можна
ітератувати. Отже, ми ітеруємо його і вітаємо кожну людину по черзі.
Зрештою, якщо `@names` — це щось інше, Ruby автоматично перетворює його
на рядок і виконує стандартне привітання.

Розгляньмо цей ітератор детальніше:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="vi">@names</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="nb">name</span><span class="o">|</span>
  <span class="nb">puts</span> <span class="s2">"Hello </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">!"</span>
<span class="k">end</span></code></pre></figure>

`each` — це метод, який приймає блок коду і виконує його для кожного
елемента списку; а частина між `do` та `end` — це саме такий блок.
Блок схожий на анонімну функцію або `lambda`. Змінна між вертикальними
рисками — це параметр блоку.

У цьому випадку для кожного елемента списку `name` прив’язується до цього
елемента, після чого виконується вираз `puts "Hello #{name}!"`.

Більшість інших мов програмування проходить список за допомогою циклу `for`,
який у C виглядає приблизно так:

<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="k">for</span> <span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">number_of_elements</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
  <span class="n">do_something_with</span><span class="p">(</span><span class="n">element</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="p">}</span></code></pre></figure>

Це працює, але не дуже елегантно. Потрібна тимчасова змінна `i`, потрібно
знати довжину списку й пояснювати, як по ньому проходити. У Ruby підхід
набагато елегантніший: усі технічні деталі приховані в методі `each`,
вам потрібно лише сказати, що робити з кожним елементом. Усередині
`each` фактично викличе `yield "Albert"`, потім `yield "Brenda"`,
потім `yield "Charles"` і так далі.

## Блоки — яскравий блиск на краю Ruby

Справжня сила блоків проявляється, коли ви маєте справу зі складнішими
речами, ніж списки. Окрім того, що метод приховує рутинні деталі,
він може приховати підготовку, завершення та обробку помилок — усе це
невидимо для користувача.

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># Say bye to everybody</span>
<span class="k">def</span> <span class="nf">say_bye</span>
  <span class="k">if</span> <span class="vi">@names</span><span class="p">.</span><span class="nf">nil?</span>
    <span class="nb">puts</span> <span class="s2">"..."</span>
  <span class="k">elsif</span> <span class="vi">@names</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"join"</span><span class="p">)</span>
    <span class="c1"># Join the list elements with commas</span>
    <span class="nb">puts</span> <span class="s2">"Goodbye </span><span class="si">#{</span><span class="vi">@names</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s2">", "</span><span class="p">)</span><span class="si">}</span><span class="s2">.  Come back soon!"</span>
  <span class="k">else</span>
    <span class="nb">puts</span> <span class="s2">"Goodbye </span><span class="si">#{</span><span class="vi">@names</span><span class="si">}</span><span class="s2">.  Come back soon!"</span>
  <span class="k">end</span>
<span class="k">end</span></code></pre></figure>

Метод `say_bye` не використовує `each`. Натомість він перевіряє, чи
`@names` відповідає на метод `join`, і якщо так — використовує його.
Інакше він просто виводить змінну як рядок. Такий підхід, коли нас не
цікавить фактичний *тип* змінної, а лише те, які методи вона підтримує,
називається “Duck Typing”, як у вислові “якщо ходить як качка і крякає
як качка…”. Перевага в тому, що це не обмежує типи змінних без потреби.
Якщо хтось створить новий тип класу списку й реалізує `join` із тією ж
семантикою, що й інші списки, усе працюватиме як задумано.

## Запуск скрипта

Ось і клас MegaGreeter; решта файлу просто викликає методи цього класу.
Є ще одна хитрість, на яку варто звернути увагу: рядок

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">if</span> <span class="kp">__FILE__</span> <span class="o">==</span> <span class="vg">$0</span></code></pre></figure>

`__FILE__` — магічна змінна, що містить ім’я поточного файлу. `$0` — ім’я
файлу, яким запущено програму. Ця перевірка означає: “Якщо це головний
використовуваний файл…”. Це дозволяє використовувати файл як бібліотеку
і не виконувати код у цьому контексті, але якщо файл використовується як
виконуваний — код виконується.

## Вітаємо зі знайомством

Ось і все для швидкого туру Ruby. Є ще багато чого досліджувати:
різні керувальні структури Ruby; використання блоків і `yield`;
модулі як міксини; і багато іншого. Сподіваюся, це знайомство з Ruby
залишило у вас бажання дізнатися більше.

Якщо так, завітайте до розділу [Документація](/uk/documentation/),
де зібрано посилання на посібники та туторіали, які безкоштовно
доступні онлайн.
