La prima volta che darai un’occhiata a del codice scritto in Ruby, ti
farà venire in mente altri linguaggi di programmazione che hai già
usato. Questo non è un caso: molti aspetti sintattici risulteranno
familiari a coloro che conoscono Perl, Python e Java (tra gli altri),
quindi se hai già usato uno di questi linguaggi, imparare Ruby sarà
facilissimo.
{: .summary}

Questo documento contiene due sezioni principali: la prima descrive che
cosa gli utenti che conoscono altri linguaggi possono aspettarsi quando
proveranno Ruby, mentre la seconda entra un po’ di più nel dettaglio
sulle caratteristiche di Ruby e sul come si possano paragonare a quanto
ti è già familiare.

## Cosa c’è da aspettarsi: Da *Linguaggio X* a Ruby

* [Da C/C++ a Ruby](to-ruby-from-c-and-cpp/)
* [Da Java a Ruby](to-ruby-from-java/)
* [Da Perl a Ruby](to-ruby-from-perl/)
* [Da PHP a Ruby](to-ruby-from-php/)
* [Da Python a Ruby](to-ruby-from-python/)

## Caratteristiche importanti e peculiarità

In questa sezione sono descritte brevemente alcune caratteristiche
particolari di Ruby.

### Iterazione

Due caratteristiche che si discostano da quello che puoi aver già visto
in altri linguaggi sono i “blocchi” e gli iteratori. Invece di iterare
su un indice (come in C, C++, o Java pre-1.5), o su una lista (come il
`for (@a) {...}` di Perl o il `for i in aList: ...` di Python),
con Ruby vedrai spesso costrutti come:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="n">una_lista</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">questo_elemento</span><span class="o">|</span>
  <span class="c1"># Dentro il blocco:</span>
  <span class="c1"># facciamo qualcosa con questo_elemento</span>
<span class="k">end</span></code></pre></figure>

Per maggiori informazioni su `each` e simili (`collect`, `find`,
`inject`, `sort`, ecc.) vedi `ri Enumerable`
(e poi `ri Enumerable#nome_funzione`).

### Ogni cosa ha un valore

Non c’è differenza tra un’espressione e uno statement: ogni cosa ha un
valore, anche se tale valore è nullo (nil):

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="n">x</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">y</span> <span class="o">=</span> <span class="mi">11</span>
<span class="n">z</span> <span class="o">=</span> <span class="k">if</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="n">y</span>
      <span class="kp">true</span>
    <span class="k">else</span>
      <span class="kp">false</span>
    <span class="k">end</span>
<span class="n">z</span> <span class="c1"># =&gt; true</span></code></pre></figure>

### I Simboli *non* sono Stringhe!

Molti neofiti di Ruby hannno difficoltà a capire cosa sono i simboli
(Symbols) e a che cosa servono. I simboli possono essere intesi, di
fatto, come degli identificatori usati per riferirsi ad altri oggetti.
Per capire la differenza, prova a scrivere le espressioni seguenti in
`irb`\:

<figure class="highlight"><pre><code class="language-irb" data-lang="irb"><span class="gp">irb(main):001:0&gt;</span><span class="w"> </span><span class="ss">:pippo</span><span class="p">.</span><span class="nf">object_id</span> <span class="o">==</span> <span class="ss">:pippo</span><span class="p">.</span><span class="nf">object_id</span>
<span class="p">=&gt;</span> <span class="kp">true</span>
<span class="gp">irb(main):002:0&gt;</span><span class="w"> </span><span class="s2">"pippo"</span><span class="p">.</span><span class="nf">object_id</span> <span class="o">==</span> <span class="s2">"pippo"</span><span class="p">.</span><span class="nf">object_id</span>
<span class="p">=&gt;</span> <span class="kp">false</span>
<span class="gp">irb(main):003:0&gt;</span></code></pre></figure>

Il metodo `object_id` ritorna l’identità di un’oggetto. Se due oggetti
hanno la stessa `object_id` allora sono di fatto la stessa cosa (puntano
entrambi al medesimo oggetto in memoria).

Come puoi vedere, una volta usato un simbolo, qualsiasi altro simbolo
con lo stesso nome si riferirà allo stesso oggetto in memoria, e ognuno
di questi simboli ritornerà quindi la medesima `object_id`.

Diamo un’occhiata più da vicino alle stringhe (“pippo”) nella seconda
espressione: ognuna delle due stringhe ha una propria `object_id`, cioè
mappa un oggetto diverso in memoria. Ciò non avviene con simboli con lo
stesso nome, che puntano sempre al medesimo oggetto. Se sei indeciso se
usare una stringa o un simbolo, pensa a cosa è più importante a seconda
del caso: l’identità di un’oggetto (per esempio una chiave di una Hash)
o il contenuto (“pippo”, nell’esempio precedente).

### Ogni cosa è un oggetto

Questa frase non è un’iperbole: anche classi e numeri interi sono
oggetti, puoi fare con loro le stesse cose che puoi fare con qualsiasi
altro oggetto:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># Questo è la stessa cosa di:</span>
<span class="c1"># class MyClass</span>
<span class="c1">#   attr_accessor :instance_var</span>
<span class="c1"># end</span>
<span class="no">MyClass</span> <span class="o">=</span> <span class="no">Class</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
  <span class="nb">attr_accessor</span> <span class="ss">:instance_var</span>
<span class="k">end</span></code></pre></figure>

### Costanti variabili

Le costanti non sono realmente “costanti”. Se modifichi una costante che
è già stata inizializzata, questo causerà un messaggio di errore, ma non
interromperà l’esecuzione del programma. Tuttavia questo **non** vuol
dire che tu debba *per forza* ridefinire delle costanti!

### Convenzioni sui nomi

Ruby usa delle specifiche convenzioni sui nomi dei suoi elementi:

* Se un’identificatore inizia con una maiuscola è una costante.
* Se inizia con il simbolo del dollaro (`$`) è una variabile globale.
* Se inizia con `@` è una variabile di istanza.
* Se inizia con `@@` è una variabile di classe.

Tuttavia i metodi possono avere un’iniziale maiuscola, anche se questo
può causare confusione, come nell’esempio seguente:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="no">Costante</span> <span class="o">=</span> <span class="mi">10</span>
<span class="k">def</span> <span class="nf">Costante</span>
  <span class="mi">11</span>
<span class="k">end</span></code></pre></figure>

In questo modo, `Costante` è 10, ma `Costante()` è 11.

### Parametri nominali

Come in Python, dalla versione 2.0 di Ruby è possibile definire metodi con
parametri nominali:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">consegna</span><span class="p">(</span><span class="ss">da: </span><span class="s1">'A'</span><span class="p">,</span> <span class="ss">a: </span><span class="kp">nil</span><span class="p">,</span> <span class="ss">via: </span><span class="s1">'mail'</span><span class="p">)</span>
  <span class="s2">"Invio da </span><span class="si">#{</span><span class="n">da</span><span class="si">}</span><span class="s2"> a </span><span class="si">#{</span><span class="n">a</span><span class="si">}</span><span class="s2"> via </span><span class="si">#{</span><span class="n">via</span><span class="si">}</span><span class="s2">."</span>
<span class="k">end</span>

<span class="n">consegna</span><span class="p">(</span><span class="ss">a: </span><span class="s1">'B'</span><span class="p">)</span>
<span class="c1"># =&gt; "Invio da A a B via mail."</span>
<span class="n">consegna</span><span class="p">(</span><span class="ss">via: </span><span class="s1">'Pony Express'</span><span class="p">,</span> <span class="ss">da: </span><span class="s1">'B'</span><span class="p">,</span> <span class="ss">a: </span><span class="s1">'A'</span><span class="p">)</span>
<span class="c1"># =&gt; "Invio da B a A via Pony Express."</span></code></pre></figure>

### Verità universale

In Ruby ogni cosa eccetto **nil** e **false** è interpretato come
*true*, mentre in C, Python e molti altri linguaggi, 0 e magari anche
altri valori sono interpretati come *false*.

Diamo un’occhiata al seguente codice in Python (questo esempio si
applica anche ad altri linguaggi):

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="c1"># in Python
</span><span class="k">if</span> <span class="mi">0</span><span class="p">:</span>
  <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">0 è true</span><span class="sh">"</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
  <span class="nf">print</span><span class="p">(</span><span class="sh">"</span><span class="s">0 è false</span><span class="sh">"</span><span class="p">)</span></code></pre></figure>

Questo stamperà “0 è false”, mentre l’equivalente in Ruby:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># in Ruby</span>
<span class="k">if</span> <span class="mi">0</span>
  <span class="nb">puts</span> <span class="s2">"0 è true"</span>
<span class="k">else</span>
  <span class="nb">puts</span> <span class="s2">"0 è false"</span>
<span class="k">end</span></code></pre></figure>

Stampa “0 è true”.

### I modificatori di accesso si applicano fino alla fine dello scope

Nel seguente codice Ruby:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">MiaClass</span>
  <span class="kp">private</span>
  <span class="k">def</span> <span class="nf">un_metodo</span><span class="p">;</span> <span class="kp">true</span><span class="p">;</span> <span class="k">end</span>
  <span class="k">def</span> <span class="nf">un_altro_metodo</span><span class="p">;</span> <span class="kp">false</span><span class="p">;</span> <span class="k">end</span>
<span class="k">end</span></code></pre></figure>

Ci si potrebbe aspettare che `un_altro_metodo` sia pubblico, ma non è
così: il modificatore di accesso `private` continua fino alla fine dello
scope, o fino a quando un altro modificatore di accesso venga
specificato.

I metodi sono pubblici di default:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">MyClass</span>
  <span class="c1"># un_metodo è pubblico</span>
  <span class="k">def</span> <span class="nf">un_metodo</span><span class="p">;</span> <span class="kp">true</span><span class="p">;</span> <span class="k">end</span>

  <span class="kp">private</span>

  <span class="c1"># un_altro_metodo è privato</span>
  <span class="k">def</span> <span class="nf">un_altro_metodo</span><span class="p">;</span> <span class="kp">false</span><span class="p">;</span> <span class="k">end</span>
<span class="k">end</span></code></pre></figure>

`public`, `private` e `protected` sono, di fatto, dei metodi, e come tali
accettano anche dei parametri. Per modificare la visibilità di un solo metodo,
per esempio, è sufficiente passare un simbolo a tale metodo come parametro di
un modificatore di accesso per cambiarne la visibilità.

### Accesso ai metodi

In Java, `public` significa che un determinato metodo è accessibile da
tutti. `protected` vuol dire invece che solamente le istanze della
classe o delle sue classi derivate e classi nello stesso package possono
accedere al metodo, e `private` implica che nessuno tranne le istanze
della medesima classe ha accesso al metodo.

Ruby differisce leggermente: `public` vuol dire sempre pubblico, ma
`private` implica che i metodi sono accessibili *solo quando non sono
chiamati con un ricevente esplicito*, solamente **self** può essere
usato come ricevente per una chiamata ad un metodo pubblico.

`protected` è il più inusuale dei tre. Un metodo protetto può essere chiamato
da un’istanza della classe o delle sue derivate, ma anche con un’altra istanza
come receiver. Per chiarificare meglio il concetto, consideriamo questo
semplice esempio adattato dalle [Ruby Language FAQ][faq]:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Test</span>
  <span class="c1"># public per default</span>
  <span class="k">def</span> <span class="nf">identifier</span>
    <span class="mi">99</span>
  <span class="k">end</span>

  <span class="k">def</span> <span class="nf">==</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
    <span class="n">identifier</span> <span class="o">==</span> <span class="n">other</span><span class="p">.</span><span class="nf">identifier</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="n">t1</span> <span class="o">=</span> <span class="no">Test</span><span class="p">.</span><span class="nf">new</span>  <span class="c1"># =&gt; #&lt;Test:0x34ab50&gt;</span>
<span class="n">t2</span> <span class="o">=</span> <span class="no">Test</span><span class="p">.</span><span class="nf">new</span>  <span class="c1"># =&gt; #&lt;Test:0x342784&gt;</span>
<span class="n">t1</span> <span class="o">==</span> <span class="n">t2</span>       <span class="c1"># =&gt; true</span>

<span class="c1"># rendiamo `identifier' protetto, e viene sempre</span>
<span class="c1"># ritornato true, perchè t2 è pur sempre un'istanza di Test</span>

<span class="k">class</span> <span class="nc">Test</span>
  <span class="kp">protected</span> <span class="ss">:identifier</span>
<span class="k">end</span>

<span class="n">t1</span> <span class="o">==</span> <span class="n">t2</span>  <span class="c1"># =&gt; true</span>

<span class="c1"># ora rendiamo `identifier' privato</span>

<span class="k">class</span> <span class="nc">Test</span>
  <span class="kp">private</span> <span class="ss">:identifier</span>
<span class="k">end</span>

<span class="n">t1</span> <span class="o">==</span> <span class="n">t2</span>
<span class="c1"># NoMethodError: private method `identifier' called for #&lt;Test:0x342784&gt;</span></code></pre></figure>

### Classi aperte

In Ruby, tutte le classi sono “aperte”. Questo vuol dire che puoi aggiungere
metodi e variabili e cambiarle in qualsiasi momento, e questo vale anche per
classi interne, come `Integer` o anche `Object`, il “genitore” di tutti gli
oggetti. Ruby on Rails, per esempio, definisce una serie di metodi per fare
operazioni temporali con oggetti `Integer`\:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Integer</span>
  <span class="k">def</span> <span class="nf">hours</span>
    <span class="nb">self</span> <span class="o">*</span> <span class="mi">3600</span> <span class="c1"># numero di secondi in un'ora</span>
  <span class="k">end</span>
  <span class="k">alias</span> <span class="n">hour</span> <span class="n">hours</span>
<span class="k">end</span>

<span class="c1"># 14 ore dalla mezzanotte del primo gennaio 2006</span>
<span class="no">Time</span><span class="p">.</span><span class="nf">mktime</span><span class="p">(</span><span class="mi">2006</span><span class="p">,</span> <span class="mo">01</span><span class="p">,</span> <span class="mo">01</span><span class="p">)</span> <span class="o">+</span> <span class="mi">14</span><span class="p">.</span><span class="nf">hours</span> <span class="c1"># =&gt; Sun Jan 01 14:00:00</span></code></pre></figure>

### Metodi con nomi “strani”

In Ruby, i nomi dei metodi possono terminare con punti esclamativi o
interrogativi. Per convenzione, metodi che rappresentano delle risposte
a delle domande (es. `Array#empty?` ritorna **true** se il
ricevente è vuoto) finiscono con un punto interrogativo, mentre metodi
potenzialmente “pericolosi” (modificano il ricevente o i gli argomenti,
`exit!` ecc.) finiscono, sempre per convenzione, con un punto
esclamativo.

Non tutti i metodi che cambiano i propri argomenti finiscono con un
punto esclamativo, però. Questo è il caso di `Array#replace` che
sostituisce il contenuto di un array con il contenuto di un altro array,
semplicemente perchè non avrebbe molto senso avere un metodo come questo
che non modifica il ricevente.

### Metodi singleton

I metodi singleton sono dei metodi *ad hoc* per singoli oggetti, e sono
pertanto definibili sull’oggetto per il quale sono stati definiti.

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Automobile</span>
  <span class="k">def</span> <span class="nf">ispeziona</span>
    <span class="s2">"Macchina a buon mercato"</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="n">porsche</span> <span class="o">=</span> <span class="no">Automobile</span><span class="p">.</span><span class="nf">new</span>
<span class="n">porsche</span><span class="p">.</span><span class="nf">ispeziona</span> <span class="c1"># =&gt; Macchina a buon mercato</span>
<span class="k">def</span> <span class="nc">porsche</span><span class="o">.</span><span class="nf">ispeziona</span>
  <span class="s2">"Macchina costosa"</span>
<span class="k">end</span>

<span class="n">porsche</span><span class="p">.</span><span class="nf">ispeziona</span> <span class="c1"># =&gt; Macchina costosa</span>

<span class="c1"># Gli altri oggetti non sono affetti dalla ridefinizione</span>
<span class="n">altra_auto</span> <span class="o">=</span> <span class="no">Automobile</span><span class="p">.</span><span class="nf">new</span>
<span class="n">altra_auto</span><span class="p">.</span><span class="nf">ispeziona</span> <span class="c1"># =&gt; Macchina a buon mercato</span></code></pre></figure>

### Metodi Mancanti

Ruby non si arrende se non riesce a trovare un metodo che risponde ad un
particolare messaggio, e chiama il metodo `method_missing` con il nome
del metodo non trovato e i relativi argomenti. Di default,
`method_missing` causa un’eccezione NameError, ma è possibile ridefinirlo
a seconda delle esigenze di una particolare applicazione, e così fanno
molte librerie. Ecco un esempio:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># id è il nome del metodo chiamato, l'asterisco</span>
<span class="c1"># fa si che tutti gli argomenti del metodo siano</span>
<span class="c1"># immagazzinati in un array chiamato 'argomenti'</span>
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="nb">id</span><span class="p">,</span> <span class="o">*</span><span class="n">argomenti</span><span class="p">)</span>
  <span class="nb">puts</span> <span class="s2">"Il metodo </span><span class="si">#{</span><span class="nb">id</span><span class="si">}</span><span class="s2"> è inesistente - è stato chiamato con "</span> <span class="o">+</span>
       <span class="s2">"i seguenti argomenti: </span><span class="si">#{</span><span class="n">argomenti</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">"</span>
<span class="k">end</span>

<span class="n">__</span> <span class="ss">:a</span><span class="p">,</span> <span class="ss">:b</span><span class="p">,</span> <span class="mi">10</span>
<span class="c1"># =&gt; l metodo #{id} è inesistente - è stato chiamato</span>
<span class="c1"># con i seguenti argomenti: a, b, 10</span></code></pre></figure>

Questo esempio stampa i dettagli della chiamata, ma è possibile gestire
il messaggio nel modo più appropriato, a seconda delle proprie esigenze.

### Scambi di messaggi, non chiamate a funzioni

Una chiamata ad un metodo è, di fatto, un **messaggio** per un altro
oggetto:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># Questo:</span>
<span class="mi">1</span> <span class="o">+</span> <span class="mi">2</span>
<span class="c1"># è equivalente a:</span>
<span class="mi">1</span><span class="p">.</span><span class="nf">+</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="c1"># che è lo stesso di</span>
<span class="mi">1</span><span class="p">.</span><span class="nf">send</span> <span class="s2">"+"</span><span class="p">,</span> <span class="mi">2</span></code></pre></figure>

### I blocchi sono degli oggetti, ma non lo sanno ancora

I blocchi (ma chiamiamoli pure *closure*), sono usati moltissimo nella
libreria standard. Per chiamare un blocco, è possibile usare `yield`
oppure rendere il blocco un oggetto `Proc` aggiungendo un argomento
speciale, così:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">blocco</span><span class="p">(</span><span class="o">&amp;</span><span class="n">il_blocco</span><span class="p">)</span>
  <span class="c1"># Qui dentro, il_blocco è il blocco passato al metodo:</span>
  <span class="n">il_blocco</span> <span class="c1"># ritorna il blocco</span>
<span class="k">end</span>
<span class="n">sommatore</span> <span class="o">=</span> <span class="n">blocco</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="o">|</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span> <span class="p">}</span>
<span class="c1"># sommatore è ora un oggetto Proc</span>
<span class="n">sommatore</span><span class="p">.</span><span class="nf">class</span> <span class="c1"># =&gt; Proc</span></code></pre></figure>

È possibile anche creare dei blocchi fuori da chiamate a metodi,
semplicemente chiamando `Proc.new` con un blocco o chiamando il metodo
`lambda`.

Allo stesso modo, anche i metodi sono pur sempre oggetti:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="nb">method</span><span class="p">(</span><span class="ss">:puts</span><span class="p">).</span><span class="nf">call</span> <span class="s2">"puts è un oggetto!"</span>
<span class="c1"># =&gt; puts è un oggetto!</span></code></pre></figure>

### Gli operatori sono “zucchero sintattico”

Molti degli operatori sono solamente dello “zucchero sintattico” (con
alcune regole di precendenza però) per delle chiamate a dei metodi. È
possibile, per esempio, ridefinire il metodo “+” della classe Integer:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Integer</span>
  <span class="c1"># Puoi farlo, ma è meglio di no!</span>
  <span class="k">def</span> <span class="nf">+</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
    <span class="nb">self</span> <span class="o">-</span> <span class="n">other</span>
  <span class="k">end</span>
<span class="k">end</span></code></pre></figure>

Non c’è nemmeno bisogno di usare `operator+`, come in C++.

È possibile anche definire un modo di accedere a uno specifico
elemento come in un array, definendo i metodi `[]` e `[]=`, mentre per
definire metodi unari + e – (pensa a +1 e -2, ad esempio), bisogna
definire, rispettivamente, i metodi `+@` e `-@`.

I seguenti operatori però **non** sono zucchero sintattico: non sono
metodi e non possono essere ridefiniti:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="o">=</span><span class="p">,</span> <span class="o">..</span><span class="p">,</span> <span class="o">...</span><span class="p">,</span> <span class="ow">not</span><span class="p">,</span> <span class="o">&amp;&amp;</span><span class="p">,</span> <span class="ow">and</span><span class="p">,</span> <span class="o">||</span><span class="p">,</span> <span class="ow">or</span><span class="p">,</span> <span class="o">::</span></code></pre></figure>

Inoltre, `+=`, `*=` ecc. sono solo abbreviazioni di
`var = var + other_var`, `var = var * other_var`, ecc. e quindi
non possono essere ridefiniti.

## Per saperne di più

Quando sei pronto per imparare di più su Ruby, dai un’occhiata alla
sezione [Documentazione](/it/documentation/).



[faq]: http://ruby-doc.org/docs/ruby-doc-bundle/FAQ/FAQ.html
