Cuando te enfrentas por primera vez a código escrito en Ruby,
probablemente te recuerde otros lenguajes que hayas usado. Esto es a
propósito. La mayor parte de la sintaxis es familiar para los usuarios
de Perl, Python y Java (entre otros lenguajes), así que si has usado
alguno de estos, aprender Ruby será muy fácil.
{: .summary}

Este documento contiene dos secciones. La primera intenta ser un resumen
de lo que puedes esperar ver al aprender Ruby viniendo de otro lenguaje.
La segunda sección se enfoca en determinadas funcionalidades del
lenguaje y cómo podrían compararse a lo que ya puedas estar
familiarizado.

## Qué esperar: *Lenguaje X* a Ruby

* [A Ruby desde Java](to-ruby-from-java/)
* [A Ruby desde PHP](to-ruby-from-php/)
* [A Ruby desde Python](to-ruby-from-python/)

Estamos en proceso de traducir todos estos artículos, pero mientras lo
hacemos no queremos privarte de que los leas en inglés:

* [To Ruby From C and C++](/en/documentation/ruby-from-other-languages/to-ruby-from-c-and-cpp/)
  (en inglés)
* [To Ruby From Java](/en/documentation/ruby-from-other-languages/to-ruby-from-java/)
  (en inglés)
* [To Ruby From Perl](/en/documentation/ruby-from-other-languages/to-ruby-from-perl/)
  (en inglés)
* [To Ruby From PHP](/en/documentation/ruby-from-other-languages/to-ruby-from-php/)
  (en inglés)


## Funcionalidades importantes del lenguaje y algunas advertencias

Aquí tienes algunas referencias y consejos sobre funcionalidades de Ruby
que verás mientras lo aprendes.

### Iteración

Dos funcionalidades de Ruby que se diferencian de lo que puedes haber
visto previamente, y que toma cierto tiempo acostumbrarse a ellas, son
los “bloques” e iteradores. En vez de recorrer un índice (como con C,
C++, o Java anterior al 1.5), o recorrer una lista (como el
`for (@a) {...}` de Perl, o `for i in aList: ...` en Python,
con Ruby verás muy frecuentemente código de este estilo:

<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">este_item</span><span class="o">|</span>
  <span class="c1"># Estamos dentro del bloque.</span>
  <span class="c1"># Trabaja con este_item.</span>
<span class="k">end</span></code></pre></figure>

Para obtener más información sobre `each` (y sus amigos `collect`,
`find`, `inject`, `sort`, etc.), ejecuta `ri Enumerable` (y después
`ri Enumerable#nombre_del_metodo`).

### Todo tiene un valor

No hay diferencia entre una expresión y un comando. Todo tiene un valor,
incluso si ese valor es **nil**. Esto es posible:

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

### Los symbols (símbolos) no son strings especiales

A muchos novatos en Ruby les cuesta entender qué son los symbols, y qué
utilidad pueden tener.

Los symbols pueden ser descritos como identidades. Lo importante de un
Symbol es **quién** es, no **qué** es. Arranca `irb` y experimenta la
diferencia:

<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">:jorge</span><span class="p">.</span><span class="nf">object_id</span> <span class="o">==</span> <span class="ss">:jorge</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">"jorge"</span><span class="p">.</span><span class="nf">object_id</span> <span class="o">==</span> <span class="s2">"jorge"</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>

El método `object_id` retorna la identidad de un objeto. Si dos objetos
tienen el mismo `object_id`, son el mismo objeto (apuntan al mismo
objeto en la memoria).

Como puedes ver, una vez que has usado un Symbol, cualquier otro Symbol
con los mismos caracteres referencia al mismo objeto en memoria. Para
dos symbols que representan los mismos caracteres, el `object_id` es el
mismo.

Ahora veamos el String (“jorge”). El `object_id` no es el mismo. Eso
significa que representan a dos objetos diferentes en memoria. Siempre
que uses un nuevo String, Ruby reserva memoria para él.

Si tienes dudas sobre usar un Symbol o un String, considera qué es más
importante: la identidad de un objeto (por ejemplo la Key de un Hash), o
el contenido (en nuestro ejemplo, “jorge”).

### Todo es un objeto

“Todo es un objeto” no es una exageración. Incluso las clases y los
enteros son objetos, y puedes hacer con ellos las mismas cosas que con
cualquier otro objeto:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># Esto es lo mismo que:</span>
<span class="c1"># class MiClase</span>
<span class="c1">#   attr_accessor :variable_de_instancia</span>
<span class="c1"># end</span>
<span class="no">MiClase</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">:variable_de_instancia</span>
<span class="k">end</span></code></pre></figure>

### Constantes variables

Las constantes no son realmente… constantes. Si modificas una constante
previamente inicializada, Ruby disparará una advertencia, pero no
detendrá tu programa. De todas formas, eso no quiere decir que
**deberías** redefinir tus constantes.

### Convenciones de sintaxis

Ruby impone algunas convenciones de sintaxis. Si un identificador
comienza con una letra mayúscula, es una constante. Si comienza con un
símbolo de moneda (`$`), es una variable global. Si comienza con `@`, es
una variable de instancia. Si comienza con `@@`, es una variable de
clase.

Sin embargo, los nombres de los métodos tienen permitido comenzar con
letras mayúsculas. Esto puede confundirte, como muestra el siguiente
ejemplo:

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

Ahora `Constante` vale 10, pero `Constante()` retorna 11.

### Falsos parámetros nombrados

A diferencia de Python, Ruby no tiene parámetros nombrados. Sin embargo,
pueden ser emulados mediante el uso de symbols y hashes. Ruby on Rails,
entre otros, usa esto a discreción. Por ejemplo:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">parametros_con_nombre</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
  <span class="n">params</span>
<span class="k">end</span>
<span class="n">parametros_con_nombre</span><span class="p">(</span><span class="ss">:param_uno</span> <span class="o">=&gt;</span> <span class="mi">10</span><span class="p">,</span> <span class="ss">:param_dos</span> <span class="o">=&gt;</span> <span class="mi">42</span><span class="p">)</span>
<span class="c1"># =&gt; {:param_uno=&gt;10, :param_dos=&gt;42}</span></code></pre></figure>

### La verdad universal

En Ruby, todo excepto **nil** y **false** es considerado **true**. En C,
Python y muchos otros lenguajes, **0** y posiblemente otros valores,
como listas vacías, son considerados **false**. Examina el siguiente
código Python (el ejemplo aplica también a otros lenguajes):

<figure class="highlight"><pre><code class="language-python" data-lang="python"><span class="c1"># en 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 es verdadero</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 es falso</span><span class="sh">"</span><span class="p">)</span></code></pre></figure>

Esto imprimirá “0 es falso”. El equivalente en Ruby:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># en Ruby</span>
<span class="k">if</span> <span class="mi">0</span>
  <span class="nb">puts</span> <span class="s2">"0 es verdadero"</span>
<span class="k">else</span>
  <span class="nb">puts</span> <span class="s2">"0 es falso"</span>
<span class="k">end</span></code></pre></figure>

Imprime “0 es verdadero”.

### Los modificadores de acceso aplican hasta el fin del alcance

En el siguiente código Ruby,

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">MiClase</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">otro_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>

Puede ser que esperes que `otro_metodo` sea de alcance público. Esto no
es así. El modificador de acceso `private` continúa hasta el fin del
alcance, o hasta que aparezca un nuevo modificador de acceso, lo que
ocurra primero. Por defecto, los métodos son públicos:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">MiClase</span>
  <span class="c1"># Ahora un_metodo es público</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"># otro_metodo es privado</span>
  <span class="k">def</span> <span class="nf">otro_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` y `protected` en realidad son métodos, así que pueden recibir parámetros. Si pasas un símbolo a uno de ellos, la visibilidad de ese método es alterada.

### Acceso a los métodos

En Java, `public` significa que un método puede ser accedido por
cualquiera. `protected` significa que las instancias de la clase,
instancias de sus descendientes así como también de clases en el mismo
paquete, pueden accederlo, pero nadie más. Y `private` significa que los
métodos son accesibles únicamente desde las instancias de la clase.

En Ruby esto es un poco diferente. `public` es, naturalmente, público.
`private` significa que los métodos son accesibles sólo cuando pueden
ser invocados sin un receptor explícito. Sólo **self** tiene permitido
ser el receptor de la invocación a un método privado.

Al que debemos estar atentos es a `protected`. Un método protegido puede
ser llamado desde una instancia de una clase o las instancias de sus
ancestros, pero también con otra instancia como su receptor.

Ejemplo, adaptado del [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 por defecto</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"># ahora haz `identifier' protected, todavía funciona</span>
<span class="c1"># porque protected permite la otra referencia</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"># ahora haz `identifier' private</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>

### Las clases están abiertas

Las clases de Ruby están abiertas. Puedes abrirlas, agregarles
funcionalidad y modificarlas en cualquier momento. Incluso las clases
principales, como `Integer` o incluso `Object`, el padre de todos los
objetos. Ruby on Rails define un montón de métodos para manejar el
tiempo y los horarios en `Integer`. Mira:

<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"># cantidad de segundos en una hora</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 horas desde las 00:00 del 1ro de enero del 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>

### Nombres de métodos graciosos

En Ruby, los métodos tienen permitido terminar en signos de exclamación
o interrogación. Por convención, los métodos que responden preguntas
(i.e. `Array#empty?` retorna **true** si el receptor está vacío)
terminan con un signo de interrogación. Métodos potencialmente
“peligrosos” (i.e. métodos que modifican **self** o sus argumentos,
`exit!` etc.) por convención terminan en un signo de exclamación.

De todas formas, no todos los métodos que modifican sus argumentos
terminan en signos de exclamación. `Array#replace` reemplaza el
contenido de un array con el contenido de otro array. No tiene mucho
sentido tener un método como ese que **no** modifique **self**.

### Los métodos Singleton

Los métodos Singleton son métodos-por-objeto. Sólo están disponibles en
el objeto en el que los defines.

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">class</span> <span class="nc">Automovil</span>
  <span class="k">def</span> <span class="nf">inspect</span>
    <span class="s2">"Auto barato"</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="n">porsche</span> <span class="o">=</span> <span class="no">Automovil</span><span class="p">.</span><span class="nf">new</span>
<span class="n">porsche</span><span class="p">.</span><span class="nf">inspect</span> <span class="c1"># =&gt; Auto barato</span>
<span class="k">def</span> <span class="nc">porsche</span><span class="o">.</span><span class="nf">inspect</span>
  <span class="s2">"Auto muy caro"</span>
<span class="k">end</span>

<span class="n">porsche</span><span class="p">.</span><span class="nf">inspect</span> <span class="c1"># =&gt; Auto muy caro</span>

<span class="c1"># Otros objetos no son afectados</span>
<span class="n">otro_auto</span> <span class="o">=</span> <span class="no">Automovil</span><span class="p">.</span><span class="nf">new</span>
<span class="n">otro_auto</span><span class="p">.</span><span class="nf">inspect</span> <span class="c1"># =&gt; Auto barato</span></code></pre></figure>

### Métodos faltantes

Ruby no se rinde si no puede encontrar un método que responda a un
mensaje en particular. Llama al método `method_missing` con el nombre
del método que no pudo encontrar y sus argumentos. Por defecto,
`method_missing` lanza una excepción NameError, pero puedes redefinirlo
para que se ajuste mejor a tu aplicación, y muchas bibliotecas lo hacen.
Aquí tienes un ejemplo:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># id es el nombre del método invocado, la sintaxis * recolecta</span>
<span class="c1"># todos los argumentos en un array llamado 'argumentos'</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">argumentos</span><span class="p">)</span>
  <span class="nb">puts</span> <span class="s2">"El método </span><span class="si">#{</span><span class="nb">id</span><span class="si">}</span><span class="s2"> fue invocado, pero no existe. Tiene "</span> <span class="o">+</span>
       <span class="s2">"estos argumentos: </span><span class="si">#{</span><span class="n">argumentos</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; El método __ fue invocado, pero no existe. Tiene estos</span>
<span class="c1"># argumentos: a, b, 10</span></code></pre></figure>

Este código sólo imprime los detalles de la invocación, pero eres libre
de manejar el mensaje como te parezca más apropiado.

### Pasaje de mensajes, no llamadas a funciones

Una invocación a un método, en realidad es un **mensaje** a otro objeto:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="c1"># Esto</span>
<span class="mi">1</span> <span class="o">+</span> <span class="mi">2</span>
<span class="c1"># Es lo mismo que esto ...</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"># Que es lo mismo que esto:</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>

### Los bloques son objetos, sólo que todavía no lo saben

Los bloques (cierres en realidad) son muy utilizados por la biblioteca
estándar. Para llamar a un bloque, puedes usar `yield`, o transformarlo
en un `Proc` al anexarle un parámetro especial a la lista de argumentos,
así:

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="k">def</span> <span class="nf">block</span><span class="p">(</span><span class="o">&amp;</span><span class="n">el_bloque</span><span class="p">)</span>
  <span class="c1"># Aquí dentro, el_bloque es el bloque pasado al método</span>
  <span class="n">el_bloque</span> <span class="c1"># retornar el bloque</span>
<span class="k">end</span>
<span class="n">sumador</span> <span class="o">=</span> <span class="n">block</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"># sumador ahora es un objeto Proc</span>
<span class="n">sumador</span><span class="p">.</span><span class="nf">class</span> <span class="c1"># =&gt; Proc</span></code></pre></figure>

También puedes crear bloques fuera de las invocaciones a métodos,
utilizando `Proc.new` con un bloque o llamando al método `lambda`.

Similarmente, los métodos también pueden ser objetos:

<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 es un objeto!"</span>
<span class="c1"># =&gt; ¡puts es un objeto!</span></code></pre></figure>

### Los operadores son comodidades sintácticas

La mayoría de los operadores en Ruby son simples simplificaciones
sintácticas (con algunas reglas de precedencia) para llamar a ciertos
métodos. Puedes, por ejemplo, redefinir el método `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"># Puedes, pero por favor no lo hagas</span>
  <span class="k">def</span> <span class="nf">+</span><span class="p">(</span><span class="n">otro</span><span class="p">)</span>
    <span class="nb">self</span> <span class="o">-</span> <span class="n">otro</span>
  <span class="k">end</span>
<span class="k">end</span></code></pre></figure>

No necesitas el`operator+` de C++, etc.

Incluso puedes tener acceso estilo array si defines los métodos `[]` y
`[]=`. Para definir los métodos unitarios + y – (piensa en +1 y -2), debes
definir los métodos `+@` and `-@` respectivamente.

Sin embargo, los siguientes operadores **no** son simplificaciones
sintácticas. No son métodos, y no pueden ser redefinidos:

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

Además, `+=`, `*=` etc. sólo son abreviaciones para `var = var + otra_var`,
`var = var * otra_var`, etc. y por ende no pueden ser redefinidos.

## Para saber más

Cuando estés listo para saber más sobre Ruby, visita nuestra sección de
[Documentación](/es/documentation/).



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