Bene, creiamo il nostro oggetto PersonaCordiale e usiamolo:

<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="nb">p</span> <span class="o">=</span> <span class="no">PersonaCordiale</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"Mario"</span><span class="p">)</span>
<span class="gp">=&gt; #&lt;PersonaCordiale:0x16cac @nome="Mario"&gt;</span><span class="w">
</span><span class="gp">irb(main):036:0&gt;</span><span class="w"> </span><span class="nb">p</span><span class="p">.</span><span class="nf">saluta</span>
<span class="go">Ciao Mario!
</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="nb">p</span><span class="p">.</span><span class="nf">congeda</span>
<span class="go">Arrivederci Mario, a presto.
</span><span class="p">=&gt;</span> <span class="kp">nil</span></code></pre></figure>

Una volta che l’oggetto `p` è stato creato, ricorda che il nome è Mario.
Ma cosa succede se vogliamo accedere direttamente al 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="nb">p</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>

Nulla, non si può.

## Ispezionare i contenuti di un oggetto

Le variabili di istanza sono nascoste dentro l’oggetto. Ma non sono così
nascoste: puoi vederle ogni volta che ispezioni l’oggetto e ci sono
altri modi per raggiungerle, ma Ruby ha un approccio molto orientati
agli oggetti per accedere ai dati nascosti.

Quindi quanti metodi esistono per il l’oggetto PersonaCordiale?

<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">PersonaCordiale</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">"saluta"</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">"congeda"</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>

Ci sono moltissimi metodi! Eppure ne avevamo definiti solo due: cosa sta
succedendo? Questi sono tutti i metodi per il nostro oggetto
PersonaCordiale, una lista **completa** che include anche quelli della
superclasse. Ma se volessimo vedere solo quelli che abbiamo creato noi?
Dobbiamo dirgli di non elencare il metodi della sua classe genitore
(super classe) passandogli come parametro `false`.

<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">PersonaCordiale</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">"saluta"</span><span class="p">,</span> <span class="s2">"congeda"</span><span class="p">]</span></code></pre></figure>

Ah, ora va meglio! Vediamo a quali metodi risponde la nostra classe:

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

Bene, la nostra classe conosce `saluta` e `to_s` (che significa
convertire “qualcosa” in una stringa, un metodo definito di default per
ogni oggetto), ma non conosce `name`.

## Alterare una classe: non è mai troppo tardi!

E se volessimo vedere o cambiare il nome? Ruby fornisce un modo semplice
per permetterci di accedere alle variabili di un oggetto.

<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">PersonaCordiale</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>

In Ruby, puoi aprire una classe e modificarla. I cambiamenti vengono
aggiunti a tutti gli oggetti che crei e sempre disponibili per gli
oggetti esistenti della classe. Quindi creiamo un nuovo oggetto e
“giochiamo” con la sua proprietà `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="nb">p</span> <span class="o">=</span> <span class="no">PersonaCordiale</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"Luigi"</span><span class="p">)</span>
<span class="gp">=&gt; #&lt;PersonaCordiale:0x3c9b0 @nome="Luigi"&gt;</span><span class="w">
</span><span class="gp">irb(main):048:0&gt;</span><span class="w"> </span><span class="nb">p</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="nb">p</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="nb">p</span><span class="p">.</span><span class="nf">saluta</span>
<span class="go">Ciao Luigi!
</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="nb">p</span><span class="p">.</span><span class="nf">nome</span><span class="o">=</span><span class="s2">"Francesca"</span>
<span class="p">=&gt;</span> <span class="s2">"Francesca"</span>
<span class="gp">irb(main):052:0&gt;</span><span class="w"> </span><span class="nb">p</span>
<span class="gp">=&gt; #&lt;PersonaCordiale:0x3c9b0 @name="Francesca"&gt;</span><span class="w">
</span><span class="gp">irb(main):053:0&gt;</span><span class="w"> </span><span class="nb">p</span><span class="p">.</span><span class="nf">nome</span>
<span class="p">=&gt;</span> <span class="s2">"Francesca"</span>
<span class="gp">irb(main):054:0&gt;</span><span class="w"> </span><span class="nb">p</span><span class="p">.</span><span class="nf">saluta</span>
<span class="go">Ciao Francesca!
</span><span class="p">=&gt;</span> <span class="kp">nil</span></code></pre></figure>

Usando `attr_accessor` definiamo due nuovi metodi, `nome` per ricevere
il valore e `nome=` per settarlo.

## Salutare tutti e tutto, L’AmicoDiTutti non trascura nessuno!

Questa PersonaCordiale può salutare solo una persona alla volta. Cosa
succederebbe se avessimo un amico di tutti che può salutare il mondo,
una persona o un intero elenco di persone?

Scriviamo questa volta in un file piuttosto che nell’inteprete
interattivo di Ruby IRB.

Per chiudere IRB, scrivi “quit”, “exit” o semplicemnte premi 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">AmicoDiTutti</span>
  <span class="nb">attr_accessor</span> <span class="ss">:nomi</span>

  <span class="c1"># Crea l'oggetto</span>
  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">nomi</span> <span class="o">=</span> <span class="s2">"Mondo"</span><span class="p">)</span>
    <span class="vi">@nomi</span> <span class="o">=</span> <span class="n">nomi</span>
  <span class="k">end</span>

  <span class="c1"># Saluta tutti</span>
  <span class="k">def</span> <span class="nf">saluta</span>
    <span class="k">if</span> <span class="vi">@nomi</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">@nomi</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"># @nomi è una lista di qualche tipo, allora iteriamo!</span>
      <span class="vi">@nomi</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">"Ciao </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">"Ciao </span><span class="si">#{</span><span class="vi">@nomi</span><span class="si">}</span><span class="s2">!"</span>
    <span class="k">end</span>
  <span class="k">end</span>

  <span class="c1"># Congeda tutti</span>
  <span class="k">def</span> <span class="nf">congeda</span>
    <span class="k">if</span> <span class="vi">@nomi</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">@nomi</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"># Unisci gli elementi della lista con delle virgole</span>
      <span class="nb">puts</span> <span class="s2">"Arrivederci </span><span class="si">#{</span><span class="vi">@nomi</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">. A presto!"</span>
    <span class="k">else</span>
      <span class="nb">puts</span> <span class="s2">"Arrivederci </span><span class="si">#{</span><span class="vi">@nomi</span><span class="si">}</span><span class="s2">. A presto!"</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">adt</span> <span class="o">=</span> <span class="no">AmicoDiTutti</span><span class="p">.</span><span class="nf">new</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">saluta</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">congeda</span>

  <span class="c1"># Cambia @nomi in "Paolo"</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">nomi</span> <span class="o">=</span> <span class="s2">"Paolo"</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">saluta</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">congeda</span>

  <span class="c1"># Cambia @nomi in una lista di nome</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">nomi</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Fabio"</span><span class="p">,</span> <span class="s2">"Davide"</span><span class="p">,</span> <span class="s2">"Raul"</span><span class="p">,</span>
    <span class="s2">"Giorgia"</span><span class="p">,</span> <span class="s2">"Federica"</span><span class="p">]</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">saluta</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">congeda</span>

  <span class="c1"># Cambia @nomi in nil</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">nomi</span> <span class="o">=</span> <span class="kp">nil</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">saluta</span>
  <span class="n">adt</span><span class="p">.</span><span class="nf">congeda</span>
<span class="k">end</span></code></pre></figure>

Salva questo file come “ri20min.rb” ed eseguilo così “ruby ri20min.rb”
Verrà mostrato qualcosa di simile:

    Ciao Mondo!
    Arrivederci Mondo. A presto!
    Ciao Paolo!
    Arrivederci Paolo. A presto!
    Ciao Fabio!
    Ciao Davide!
    Ciao Raul!
    Ciao Giorgia!
    Ciao Federica!
    Arrivederci Fabio, Davide, Raul, Giorgia, Federica. A presto!
    ...
    ...
{: .code}

Ci sono moltissime cose nuove in questo esempio che [possono assumere un
significato più profondo](../4/).
