So, looking deeper at our new program, notice the initial lines, which
begin with a hash mark (#). In Ruby, anything on a line after a hash
mark is a comment and is ignored by the interpreter. The first line of
the file is a special case, and under a Unix-like operating system tells
the shell how to run the file. The rest of the comments are there just
for clarity.

Our `say_hi` method has become a bit trickier:

<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>

It now looks at the `@names` instance variable to make decisions. If
it’s nil, it just prints out three dots. No point greeting nobody,
right?

## Cycling and Looping—a.k.a. Iteration

If the `@names` object responds to `each`, it is something that you can
iterate over, so iterate over it and greet each person in turn. Finally,
if `@names` is anything else, just let it get turned into a string
automatically and do the default greeting.

Let’s look at that iterator in more depth:

<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` is a method that accepts a block of code then runs that block of
code for every element in a list, and the bit between `do` and `end` is
just such a block. A block is like an anonymous function or `lambda`.
The variable between pipe characters is the parameter for this block.

What happens here is that for every entry in a list, `name` is bound to
that list element, and then the expression `puts "Hello #{name}!"` is
run with that name.

Most other programming languages handle going over a list using the
`for` loop, which in C looks something like:

<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>

This works, but isn’t very elegant. You need a throw-away variable like
`i`, have to figure out how long the list is, and have to explain how to
walk over the list. The Ruby way is much more elegant, all the
housekeeping details are hidden within the `each` method, all you need
to do is to tell it what to do with each element. Internally, the `each`
method will essentially call `yield "Albert"`, then `yield "Brenda"` and
then `yield "Charles"`, and so on.

## Blocks, the Highly Sparkling Glint on the Edge of Ruby

The real power of blocks is when dealing with things that are more
complicated than lists. Beyond handling simple housekeeping details
within the method, you can also handle setup, teardown, and errors—all
hidden away from the cares of the user.

<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>

The `say_bye` method doesn’t use `each`, instead it checks to see if
`@names` responds to the `join` method, and if so, uses it. Otherwise,
it just prints out the variable as a string. This method of not caring
about the actual *type* of a variable, just relying on what methods it
supports is known as “Duck Typing”, as in “if it walks like a duck and
quacks like a duck…”. The benefit of this is that it doesn’t
unnecessarily restrict the types of variables that are supported. If
someone comes up with a new kind of list class, as long as it implements
the `join` method with the same semantics as other lists, everything
will work as planned.

## Kicking Off the Script

So, that’s the MegaGreeter class, the rest of the file just calls
methods on that class. There’s one final trick to notice, and that’s the
line:

<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__` is the magic variable that contains the name of the current
file. `$0` is the name of the file used to start the program. This check
says “If this is the main file being used…” This allows a file to be
used as a library, and not to execute code in that context, but if the
file is being used as an executable, then execute that code.

## Consider Yourself Introduced

So that’s it for the quick tour of Ruby. There’s a lot more to explore,
the different control structures that Ruby offers; the use of blocks and
`yield`; modules as mixins; and more. I hope this taste of Ruby has left
you wanting to learn more.

If so, please head on over to our [Documentation](/en/documentation/)
area, which rounds up links to manuals and tutorials, all freely
available online.
