Now let’s create a greeter object and use it:

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):035:0&gt;</span><span class="w"> </span><span class="n">greeter</span> <span class="o">=</span> <span class="no">Greeter</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"Pat"</span><span class="p">)</span>
<span class="gp">=&gt; #&lt;Greeter:0x16cac @name="Pat"&gt;</span><span class="w">
</span><span class="gp">irb(main):036:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">say_hi</span>
<span class="go">Hi Pat!
</span><span class="p">=&gt;</span> <span class="kp">nil</span>
<span class="gp">irb(main):037:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">say_bye</span>
<span class="go">Bye Pat, come back soon.
</span><span class="p">=&gt;</span> <span class="kp">nil</span></code></pre></figure>

Once the `greeter` object is created, it remembers that the name is Pat. Hmm,
what if we want to get at the name directly?

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):038:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="o">.</span><span class="vi">@name</span>
<span class="gr">SyntaxError: (irb):38: syntax error, unexpected tIVAR, expecting '('</span></code></pre></figure>

Nope, can’t do it.

## Under the Object’s Skin

Instance variables are hidden away inside the object. They’re not
terribly hidden, you see them whenever you inspect the object, and there
are other ways of accessing them, but Ruby uses the good object-oriented
approach of keeping data sort-of hidden away.

So what methods do exist for Greeter objects?

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):039:0&gt;</span><span class="w"> </span><span class="no">Greeter</span><span class="p">.</span><span class="nf">instance_methods</span>
<span class="p">=&gt;</span> <span class="p">[</span><span class="ss">:say_hi</span><span class="p">,</span> <span class="ss">:say_bye</span><span class="p">,</span> <span class="ss">:instance_of?</span><span class="p">,</span> <span class="ss">:public_send</span><span class="p">,</span>
    <span class="ss">:instance_variable_get</span><span class="p">,</span> <span class="ss">:instance_variable_set</span><span class="p">,</span>
    <span class="ss">:instance_variable_defined?</span><span class="p">,</span> <span class="ss">:remove_instance_variable</span><span class="p">,</span>
    <span class="ss">:private_methods</span><span class="p">,</span> <span class="ss">:kind_of?</span><span class="p">,</span> <span class="ss">:instance_variables</span><span class="p">,</span> <span class="ss">:tap</span><span class="p">,</span>
    <span class="ss">:is_a?</span><span class="p">,</span> <span class="ss">:extend</span><span class="p">,</span> <span class="ss">:define_singleton_method</span><span class="p">,</span> <span class="ss">:to_enum</span><span class="p">,</span>
    <span class="ss">:enum_for</span><span class="p">,</span> <span class="ss">:&lt;=&gt;</span><span class="p">,</span> <span class="ss">:===</span><span class="p">,</span> <span class="p">:</span><span class="o">=~</span><span class="p">,</span> <span class="p">:</span><span class="o">!~</span><span class="p">,</span> <span class="ss">:eql?</span><span class="p">,</span> <span class="ss">:respond_to?</span><span class="p">,</span>
    <span class="ss">:freeze</span><span class="p">,</span> <span class="ss">:inspect</span><span class="p">,</span> <span class="ss">:display</span><span class="p">,</span> <span class="ss">:send</span><span class="p">,</span> <span class="ss">:object_id</span><span class="p">,</span> <span class="ss">:to_s</span><span class="p">,</span>
    <span class="ss">:method</span><span class="p">,</span> <span class="ss">:public_method</span><span class="p">,</span> <span class="ss">:singleton_method</span><span class="p">,</span> <span class="ss">:nil?</span><span class="p">,</span> <span class="ss">:hash</span><span class="p">,</span>
    <span class="ss">:class</span><span class="p">,</span> <span class="ss">:singleton_class</span><span class="p">,</span> <span class="ss">:clone</span><span class="p">,</span> <span class="ss">:dup</span><span class="p">,</span> <span class="ss">:itself</span><span class="p">,</span> <span class="ss">:taint</span><span class="p">,</span>
    <span class="ss">:tainted?</span><span class="p">,</span> <span class="ss">:untaint</span><span class="p">,</span> <span class="ss">:untrust</span><span class="p">,</span> <span class="ss">:trust</span><span class="p">,</span> <span class="ss">:untrusted?</span><span class="p">,</span> <span class="ss">:methods</span><span class="p">,</span>
    <span class="ss">:protected_methods</span><span class="p">,</span> <span class="ss">:frozen?</span><span class="p">,</span> <span class="ss">:public_methods</span><span class="p">,</span> <span class="ss">:singleton_methods</span><span class="p">,</span>
    <span class="p">:</span><span class="o">!</span><span class="p">,</span> <span class="ss">:==</span><span class="p">,</span> <span class="p">:</span><span class="o">!=</span><span class="p">,</span> <span class="ss">:__send__</span><span class="p">,</span> <span class="ss">:equal?</span><span class="p">,</span> <span class="ss">:instance_eval</span><span class="p">,</span> <span class="ss">:instance_exec</span><span class="p">,</span> <span class="ss">:__id__</span><span class="p">]</span></code></pre></figure>

Whoa. That’s a lot of methods. We only defined two methods. What’s going
on here? Well this is **all** of the methods for Greeter objects, a
complete list, including ones defined by ancestor classes. If we want to
just list methods defined for Greeter we can tell it to not include
ancestors by passing it the parameter `false`, meaning we don’t want
methods defined by ancestors.

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):040:0&gt;</span><span class="w"> </span><span class="no">Greeter</span><span class="p">.</span><span class="nf">instance_methods</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="p">[</span><span class="ss">:say_hi</span><span class="p">,</span> <span class="ss">:say_bye</span><span class="p">]</span></code></pre></figure>

Ah, that’s more like it. So let’s see which methods our greeter object
responds to:

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):041:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"name"</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="kp">false</span>
<span class="gp">irb(main):042:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"say_hi"</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="kp">true</span>
<span class="gp">irb(main):043:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"to_s"</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="kp">true</span></code></pre></figure>

So, it knows `say_hi`, and `to_s` (meaning convert something to a
string, a method that’s defined by default for every object), but it
doesn’t know `name`.

## Altering Classes—It’s Never Too Late

But what if you want to be able to view or change the name? Ruby
provides an easy way of providing access to an object’s variables.

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):044:0&gt;</span><span class="w"> </span><span class="k">class</span> <span class="nc">Greeter</span>
<span class="gp">irb(main):045:1&gt;</span><span class="w">   </span><span class="nb">attr_accessor</span> <span class="ss">:name</span>
<span class="gp">irb(main):046:1&gt;</span><span class="w"> </span><span class="k">end</span>
<span class="p">=&gt;</span> <span class="p">[</span><span class="ss">:name</span><span class="p">,</span> <span class="ss">:name</span><span class="o">=</span><span class="p">]</span></code></pre></figure>

In Ruby, you can reopen a class and modify it. The changes will
be present in any new objects you create and even available in existing
objects of that class. So, let’s create a new object and play with its
`@name` property.

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):047:0&gt;</span><span class="w"> </span><span class="n">greeter</span> <span class="o">=</span> <span class="no">Greeter</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"Andy"</span><span class="p">)</span>
<span class="gp">=&gt; #&lt;Greeter:0x3c9b0 @name="Andy"&gt;</span><span class="w">
</span><span class="gp">irb(main):048:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"name"</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="kp">true</span>
<span class="gp">irb(main):049:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"name="</span><span class="p">)</span>
<span class="p">=&gt;</span> <span class="kp">true</span>
<span class="gp">irb(main):050:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">say_hi</span>
<span class="go">Hi Andy!
</span><span class="p">=&gt;</span> <span class="kp">nil</span>
<span class="gp">irb(main):051:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">name</span><span class="o">=</span><span class="s2">"Betty"</span>
<span class="p">=&gt;</span> <span class="s2">"Betty"</span>
<span class="gp">irb(main):052:0&gt;</span><span class="w"> </span><span class="n">greeter</span>
<span class="gp">=&gt; #&lt;Greeter:0x3c9b0 @name="Betty"&gt;</span><span class="w">
</span><span class="gp">irb(main):053:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">name</span>
<span class="p">=&gt;</span> <span class="s2">"Betty"</span>
<span class="gp">irb(main):054:0&gt;</span><span class="w"> </span><span class="n">greeter</span><span class="p">.</span><span class="nf">say_hi</span>
<span class="go">Hi Betty!
</span><span class="p">=&gt;</span> <span class="kp">nil</span></code></pre></figure>

Using `attr_accessor` defined two new methods for us, `name` to get the
value, and `name=` to set it.

## Greeting Anything and Everything, MegaGreeter Neglects None!

This greeter isn’t all that interesting though, it can only deal with
one person at a time. What if we had some kind of MegaGreeter that could
either greet the world, one person, or a whole list of people?

Let’s write this one in a file instead of directly in the interactive
Ruby interpreter IRB.

To quit IRB, type “quit”, “exit” or just hit Control-D.

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1">#!/usr/bin/env ruby</span>

<span class="k">class</span> <span class="nc">MegaGreeter</span>
  <span class="nb">attr_accessor</span> <span class="ss">:names</span>

  <span class="c1"># Create the object</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">names</span> <span class="o">=</span> <span class="s2">"World"</span><span class="p">)</span>
    <span class="vi">@names</span> <span class="o">=</span> <span class="n">names</span>
  <span class="k">end</span>

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

  <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>
<span class="k">end</span>


<span class="k">if</span> <span class="kp">__FILE__</span> <span class="o">==</span> <span class="vg">$0</span>
  <span class="n">mg</span> <span class="o">=</span> <span class="no">MegaGreeter</span><span class="p">.</span><span class="nf">new</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_hi</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_bye</span>

  <span class="c1"># Change name to be "Zeke"</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">names</span> <span class="o">=</span> <span class="s2">"Zeke"</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_hi</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_bye</span>

  <span class="c1"># Change the name to an array of names</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">names</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Albert"</span><span class="p">,</span> <span class="s2">"Brenda"</span><span class="p">,</span> <span class="s2">"Charles"</span><span class="p">,</span>
              <span class="s2">"Dave"</span><span class="p">,</span> <span class="s2">"Engelbert"</span><span class="p">]</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_hi</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_bye</span>

  <span class="c1"># Change to nil</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">names</span> <span class="o">=</span> <span class="kp">nil</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_hi</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">say_bye</span>
<span class="k">end</span></code></pre></figure>

Save this file as “ri20min.rb”, and run it as “ruby ri20min.rb”. The
output should be:

    Hello World!
    Goodbye World.  Come back soon!
    Hello Zeke!
    Goodbye Zeke.  Come back soon!
    Hello Albert!
    Hello Brenda!
    Hello Charles!
    Hello Dave!
    Hello Engelbert!
    Goodbye Albert, Brenda, Charles, Dave, Engelbert.  Come
    back soon!
    ...
    ...
{: .code}

There are a lot of new things thrown into this final example that we
[can take a deeper look at.](../4/)
