Símbolos Ruby

Un símbolo es parecido a una variable pero está precedido por dos puntos (:). Por ejemplo: :accion, :nombre. Puedes pensar en símbolos como cadenas que fueron convertidas mágicamente en constantes. Alternativamente, puedes considerar a los dos puntos que preceden a un símbolo como "aquello que" se llama", entonces :id es "lo que se llama id".

Un símbolo es el objeto más básico que se puede crear en Ruby. Es sólo un nombre un id interno. Los símoblos son útiles proque se refieren al mismo objeto a lo largo de todo el programa. Los símbolos son más eficientes que las cadenas. Dos cadenas con el mismo contenido son dos objetos diferentes pero para cualquier nombre hay sólo un objeto, lo que significa que podemos ahorrar tiempo y memoria.

Observa el ejemplo siguiente: p039simbolo.rb

1 puts "cadena".object_id
2 puts "cadena".object_id
3 puts :simbolo.object_id
4 puts :simbolo.object_id

El resultado es el siguiente: (si ejecutas el programa en tu computadora seguramente vas a botener valores diferentes)

¿Entonces, cuándo usamos una cadena y cuándo un símbolo?

  • Si el contenido (la secuencia de caracteres) del objeto son importantes, utiliza una cadena.
  • Si la identidad del objeto es importante, utiliza un símbolo.

Ruby utiliza símbolos y mantiene una tabla de símbolos para contenerlos. Los símbolos son nombres -nombres de variables de instancia, de métodos o de clases. Si hay un método llamado controla_pelicula, existe automáticamente un símbolo :controla_pelicula. Ruby es un lenguaje interpretado, así es que mantiene su tabla de símbolos siempre disponible. Puedes ver que hay en esta tabla llamando Symbol.all_symbols

Un objeto de la clase Symbol es creado anteponiendo dos puntos (:) a unoperador, una cadena, variable, constante, clase o módulo. El símbolo va a ser único para cada nombre pero no se refiere a una instancia en particular durante la ejecución del programa. Entonces, si Alfredo es una constante en un contexto, un método en otro y una clase en un tercero, el símbolo :Fred es el mismo objeto en los tres contextos.

Podemos ilustrar lo anterion con el programa p039simbolo.rb

 1 class Prueba
 2   puts :Prueba.object_id.to_s
 3   def prueba
 4     puts :prueba.object_id.to_s  
 5     @prueba = 10
 6     puts :prueba.object_id.to_s
 7   end
 8 end
 9 t = Prueba.new
10 t.prueba

Otro ejemplo:

 1 sabes_ruby = :si
 2 
 3 if sabes_ruby == :si
 4   puts "Eres un rubyista"
 5 else
 6   puts "Empieza a aprender Ruby!"
 7 end
 8 
 9 # rubyista?

En el ejemplo anterior, :si es un símbolo. Los símbolos no contienen valores ni objetos como las variables. Son utilizados como un nombre consistente dentro del código. Por ejemplo, en el programa anterior puedes reemplazar al símbolo :si con la cadena 'si'

 1 sabes_ruby = 'si'
 2 
 3 if sabes_ruby == 'si'
 4   puts "Eres un rubyista"
 5 else
 6   puts "Empieza a aprender Ruby!"
 7 end
 8 
 9 # rubyista?

Este programa da el mismo resultado pero no es tan eficiente. Cada vez que la cadena 'yes' es utilizada, se crea un nuevo objeto almacenado por separado en memoria, mientras que los símbolos son valores de referencia únicos que son inicializados sólo una vez. En el primer ejemplo sólo un :yes existe mientras que en el segundo, dos instancias diferentes de 'yes' ocupan memoria.

Es posible convertir una cadena en un símbolo y vice-versa:

1 puts 'cadena'.to_sym.class
2 puts :simbolo.to_s.class

Los símbolos son particularmente útiles cuando quieres crear hashes y tener una distinción entre keys y valores.