Agora vamos criar e usar um objeto Anfitrião:

<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">g</span> <span class="o">=</span> <span class="no">Anfitriao</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"João"</span><span class="p">)</span>
<span class="gp">=&gt; #&lt;Anfitriao:0x16cac @nome="João"&gt;</span><span class="w">
</span><span class="gp">irb(main):036:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">diz_ola</span>
<span class="go">Ola João
</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">g</span><span class="p">.</span><span class="nf">diz_adeus</span>
<span class="go">Adeus João, volte em breve.
</span><span class="p">=&gt;</span> <span class="kp">nil</span></code></pre></figure>

Uma vez criado o objeto `g`, ele se lembra de que o nome é João. Mmm, e se
quisermos acessar diretamente o nome?

<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">g</span><span class="o">.</span><span class="vi">@nome</span>
<span class="gr">SyntaxError: compile error
(irb):52: syntax error
        from (irb):52</span></code></pre></figure>

Nope, não conseguimos.

## Objeto por Baixo da Pele

As variáveis de instância escondem-se dentro do objeto. Não estão assim
tão bem escondidas, podem ser vistas quando se inspeciona o objeto e
há outras formas de lhes acessar, mas o Ruby é fiel aos bons costumes da
programação orientada a objetos mantendo os dados o mais privados
possíveis.

Então, que métodos estão disponíveis para os objetos Anfitrião?

<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">Anfitriao</span><span class="p">.</span><span class="nf">instance_methods</span>
<span class="p">=&gt;</span> <span class="p">[</span><span class="s2">"method"</span><span class="p">,</span> <span class="s2">"send"</span><span class="p">,</span> <span class="s2">"object_id"</span><span class="p">,</span> <span class="s2">"singleton_methods"</span><span class="p">,</span>
    <span class="s2">"__send__"</span><span class="p">,</span> <span class="s2">"equal?"</span><span class="p">,</span> <span class="s2">"taint"</span><span class="p">,</span> <span class="s2">"frozen?"</span><span class="p">,</span>
    <span class="s2">"instance_variable_get"</span><span class="p">,</span> <span class="s2">"kind_of?"</span><span class="p">,</span> <span class="s2">"to_a"</span><span class="p">,</span>
    <span class="s2">"instance_eval"</span><span class="p">,</span> <span class="s2">"type"</span><span class="p">,</span> <span class="s2">"protected_methods"</span><span class="p">,</span> <span class="s2">"extend"</span><span class="p">,</span>
    <span class="s2">"eql?"</span><span class="p">,</span> <span class="s2">"display"</span><span class="p">,</span> <span class="s2">"instance_variable_set"</span><span class="p">,</span> <span class="s2">"hash"</span><span class="p">,</span>
    <span class="s2">"is_a?"</span><span class="p">,</span> <span class="s2">"to_s"</span><span class="p">,</span> <span class="s2">"class"</span><span class="p">,</span> <span class="s2">"tainted?"</span><span class="p">,</span> <span class="s2">"private_methods"</span><span class="p">,</span>
    <span class="s2">"untaint"</span><span class="p">,</span> <span class="s2">"diz_ola"</span><span class="p">,</span> <span class="s2">"id"</span><span class="p">,</span> <span class="s2">"inspect"</span><span class="p">,</span> <span class="s2">"=="</span><span class="p">,</span> <span class="s2">"==="</span><span class="p">,</span>
    <span class="s2">"clone"</span><span class="p">,</span> <span class="s2">"public_methods"</span><span class="p">,</span> <span class="s2">"respond_to?"</span><span class="p">,</span> <span class="s2">"freeze"</span><span class="p">,</span>
    <span class="s2">"diz_adeus"</span><span class="p">,</span> <span class="s2">"__id__"</span><span class="p">,</span> <span class="s2">"=~"</span><span class="p">,</span> <span class="s2">"methods"</span><span class="p">,</span> <span class="s2">"nil?"</span><span class="p">,</span> <span class="s2">"dup"</span><span class="p">,</span>
    <span class="s2">"instance_variables"</span><span class="p">,</span> <span class="s2">"instance_of?"</span><span class="p">]</span></code></pre></figure>

Uau. São muitos métodos. Nós só definimos dois métodos. O que é que
aconteceu? Bem, estes são **todos** os métodos para os objetos
Anfitrião, uma lista completa, incluindo os que estão definidos nas
super-classes de Anfitrião. Se só quisermos listar os métodos
definidos para a classe Anfitrião, podemos pedir-lhe que não inclua os
métodos dos seus ancestrais passando-lhe o parâmetro `false`, que
significa que não queremos os métodos definidos pelos seus ancestrais.

<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">Anfitriao</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="s2">"diz_adeus"</span><span class="p">,</span> <span class="s2">"diz_ola""]</span></code></pre></figure>

Há mais coisas a explorar. Vejamos a que métodos pode responder o nosso
objeto Anfitrião:

<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">g</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"nome"</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">g</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"diz_ola"</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">g</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>

Assim sabemos que responde a `diz_ola`, e `to_s` (que
significa “converter algo em uma string”, um método que está definido por
padrão para todos os objetos), mas que não reconhece `nome` como
método.

## Modificando Classes – Nunca é Tarde Demais

E se quisermos ver ou alterar o nome? Ruby oferece uma forma fácil
de fornecer acesso às variáveis de um objeto.

<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">Anfitriao</span>
<span class="gp">irb(main):045:1&gt;</span><span class="w">   </span><span class="nb">attr_accessor</span> <span class="ss">:nome</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">:nome</span><span class="p">,</span> <span class="ss">:nome</span><span class="o">=</span><span class="p">]</span></code></pre></figure>

Em Ruby, podemos abrir uma classe novamente e alterá-la. As mudanças estarão
presentes em quaisquer objetos criados e até mesmo nos objetos existentes
dessa classe. Então vamos criar um novo objeto e vamos brincar com a sua
propriedade `@nome`.

<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">g</span> <span class="o">=</span> <span class="no">Anfitriao</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"Pedro"</span><span class="p">)</span>
<span class="gp">=&gt; #&lt;Anfitriao:0x3c9b0 @nome="Pedro"&gt;</span><span class="w">
</span><span class="gp">irb(main):048:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"nome"</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">g</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="s2">"nome="</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">g</span><span class="p">.</span><span class="nf">diz_ola</span>
<span class="go">Ola Pedro
</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">g</span><span class="p">.</span><span class="nf">nome</span><span class="o">=</span><span class="s2">"Matilde"</span>
<span class="p">=&gt;</span> <span class="s2">"Matilde"</span>
<span class="gp">irb(main):052:0&gt;</span><span class="w"> </span><span class="n">g</span>
<span class="gp">=&gt; #&lt;Anfitrion:0x3c9b0 @nome="Matilde"&gt;</span><span class="w">
</span><span class="gp">irb(main):053:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">nome</span>
<span class="p">=&gt;</span> <span class="s2">"Matilde"</span>
<span class="gp">irb(main):054:0&gt;</span><span class="w"> </span><span class="n">g</span><span class="p">.</span><span class="nf">diz_ola</span>
<span class="go">Ola Matilde
</span><span class="p">=&gt;</span> <span class="kp">nil</span></code></pre></figure>

O uso de `attr_accessor` definiu dois novos métodos para nós:
`nome` para obter o valor e `nome=` para alterá-lo.

## Saudando a Tudo e a Todos, MegaAnfitriao não Esquece Ninguém!

De qualquer modo este Anfitrião não é assim tão interessante, ele só consegue
trabalhar com uma pessoa de cada vez. E se tivéssemos uma classe MegaAnfitriao
que pudesse saudar o mundo inteiro, uma pessoa ou uma lista inteira de pessoas?

Vamos escrever isto num arquivo em vez de usar diretamente o interpretador
interativo do Ruby (IRB).

Para sair do IRB, digite “quit”, “exit” ou simplesmente pressione “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">MegaAnfitriao</span>
  <span class="nb">attr_accessor</span> <span class="ss">:nomes</span>

  <span class="c1"># Criar o objecto</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">nomes</span> <span class="o">=</span> <span class="s2">"Mundo"</span><span class="p">)</span>
    <span class="vi">@nomes</span> <span class="o">=</span> <span class="n">nomes</span>
  <span class="k">end</span>

  <span class="c1"># Dizer ola a todos</span>
  <span class="k">def</span> <span class="nf">diz_ola</span>
    <span class="k">if</span> <span class="vi">@nomes</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">@nomes</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"># @nomes é uma lista de algum tipo,</span>
      <span class="c1"># assim podemos iterar!</span>
      <span class="vi">@nomes</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">nome</span><span class="o">|</span>
        <span class="nb">puts</span> <span class="s2">"Ola </span><span class="si">#{</span><span class="n">nome</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">"Ola </span><span class="si">#{</span><span class="vi">@nomes</span><span class="si">}</span><span class="s2">"</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="c1"># Dizer adeus a todos</span>
  <span class="k">def</span> <span class="nf">diz_adeus</span>
    <span class="k">if</span> <span class="vi">@nomes</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">@nomes</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"># Juntar os elementos à lista</span>
      <span class="c1"># usando a vírgula como separador</span>
      <span class="nb">puts</span> <span class="s2">"Adeus </span><span class="si">#{</span><span class="vi">@nomes</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">. Voltem em breve."</span>
    <span class="k">else</span>
      <span class="nb">puts</span> <span class="s2">"Adeus </span><span class="si">#{</span><span class="vi">@nomes</span><span class="si">}</span><span class="s2">. Volta em breve."</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">MegaAnfitriao</span><span class="p">.</span><span class="nf">new</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">diz_ola</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">diz_adeus</span>

  <span class="c1"># Alterar o nome para "Diogo"</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">nomes</span> <span class="o">=</span> <span class="s2">"Diogo"</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">diz_ola</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">diz_adeus</span>

  <span class="c1"># Alterar o nome para um vector de nomes</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">nomes</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Alberto"</span><span class="p">,</span> <span class="s2">"Beatriz"</span><span class="p">,</span> <span class="s2">"Carlos"</span><span class="p">,</span>
    <span class="s2">"David"</span><span class="p">,</span> <span class="s2">"Ernesto"</span><span class="p">]</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">diz_ola</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">diz_adeus</span>

  <span class="c1"># Alterar para nil</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">nomes</span> <span class="o">=</span> <span class="kp">nil</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">diz_ola</span>
  <span class="n">mg</span><span class="p">.</span><span class="nf">diz_adeus</span>
<span class="k">end</span></code></pre></figure>

Salve este arquivo como “ri20min.rb”, e execute-o com o comando
“ruby ri20min.rb”. O resultado deverá ser:

    Ola Mundo
    Adeus Mundo. Volta em breve.
    Ola Diogo
    Adeus Diogo. Volta em breve.
    Ola Alberto
    Ola Beatriz
    Ola Carlos
    Ola David
    Ola Ernesto
    Adeus Alberto, Beatriz, Carlos, David, Ernesto.
    Voltem em breve.
    ...
    ...
{: .code}

Há uma série de coisas novas neste exemplo às quais podemos
[observar mais profundamente](../4/)
