Sobre Simbolos (colon, dos puntos)

Hola!, Antes que todo Feliz año nuevo a todos los de esta lista y
felices fiestas.
Mi PRegunta es simple, Para que sirven y/o son exactamente los
simbolos (los dos puntos que se anteponen a una palabra…symbols).

No se aclara mucho en ninguna web.

Gracias de ante mano!

ATTE

Alberto L.

Hola Alberto,

Alberto L.
escribió:> Hola!, Antes que todo Feliz año nuevo a todos los de esta lista y

felices fiestas.

Igualmente, feliz año colisteros!!! :slight_smile:

Mi PRegunta es simple, Para que sirven y/o son exactamente los simbolos
(los dos puntos que se anteponen a una palabra…symbols).

Tu pregunta es simple, pero me temo que mi respuesta es pelín larga :wink:

Un símbolo es un objeto que consta de:

  • un nombre (los caracteres que tú indicas tras los dos puntos)
  • un id de objeto (como todos los objetos Ruby)

Visto así, un símbolo puede parecer tremendamente parecido a un string:
la gracia de ambos es que cuentan con un conjunto de caracteres, de
forma que la utilidad de ambos parece muy parecida. Además, es fácil
pasar de un string a un símbolo y viceversa:

:foo.to_s # devuelve un string “foo”
“foo”.to_sym # devuelve el objeto :foo

Sin embargo hay algunas diferencias importantes entre un símbolo y un
string:

  • Los caracteres del símbolo conforman un nombre que no puedes
    modificar. En el caso de un string sí puedes modificar los caracteres
    que lo componen.

  • El nombre de un símbolo es único a nivel global: no puedes tener dos
    símbolos diferentes con el mismo nombre en tu programa. Sin embargo, sí
    puedes tener dos strings con el mismo conjunto de caracteres.

Fíjate en el ejemplo que muestran en la API de Ruby [1]:

module One
  class Fred
  end
  $f1 = :Fred
end
module Two
  Fred = 1
  $f2 = :Fred
end
def Fred()
end
$f3 = :Fred

# he modificado las siguientes lineas del ejemplo,
# se recomienda usar object_id en lugar de id:
$f1.object_id   #=> 2514190
$f2.object_id   #=> 2514190
$f3.object_id   #=> 2514190

En este ejemplo, aunque utilizan el objeto :Fred en tres contextos
distintos, el id permanece constante (es decir, el objeto siempre es el
mismo). En el caso de los strings no es así, prueba a ejecutar varias
veces

“Fred”.object_id

en tu consola irb, obtendrás un object_id diferente en cada ocasión,
aunque la cadena de caracteres es idéntica. Es decir, esos “Fred” que
has escrito son strings diferentes, pero que contienen la misma cadena
de caracteres.

De todo esto podemos deducir que usar varias veces un símbolo es más
eficiente que usar varios strings con los mismos caracteres. Imagina,
por ejemplo, que quieres almacenar en un objeto Hash los datos de tu
amigo Pedro. Podrías usar como índice el nombre de cada dato:

pedro = { “telefono” => 1234567, … } # se genera un string
“telefono”

ahora queremos imprimir el telefono de Pedro:

puts pedro[“telefono”] # se genera OTRO string “telefono” distinto

Si en lugar de usar strings hubiéramos usado símbolos, consumiríamos la
mitad de memoria:

pedro = { :telefono => 1234567, … } # se genera un simbolo :telefono

ahora queremos imprimir el numero de Pedro:

puts pedro[:telefono] # el simbolo :telefono es unico, se usa EL MISMO

Otro ejemplo de la eficiencia de los símbolos frente a los strings: para
comprobar si dos strings son iguales se comparan carácter a carácter.
Para comprobar si dos símbolos son iguales basta con comparar si ambos
tienen el mismo object_id.

En cuanto a para qué se usan los símbolos, te remito al propio Rails, su
código fuente es un ejemplo de uso intensivo de símbolos.

Para terminar, si en algún momento dudas si utilizar un string o un
símbolo, en el Ruby Cookbook dan el siguiente consejo:

  • si el contenido (la cadena de caracteres) es importante, usa un string
  • si lo importante es la identidad del objeto, usa un símbolo

Saludos,
Raúl
[1]class Symbol - RDoc Documentation
[2]O'Reilly Media - Technology and Business Training

Es decir, un símbolo se utiliza para hacer referencia a cualquier
objeto de tu programa: una variable, una función, etc

Es como un puntero en el sentido de que a través de él llegas a un
objeto (sólo eso, no te líes con conceptos de direcciones de memoria
ni nada por el estilo).

On Jan 1, 2007, at 9:45 PM, Fernando B. wrote:

Es decir, un símbolo se utiliza para hacer referencia a cualquier
objeto de tu programa: una variable, una función, etc

Que quieres decir ahi Fernando?

– fxn

On Jan 2, 2007, at 1:15 PM, Fernando B. wrote:

Hey! :slight_smile:

los dos puntos se utilizan para
referirse al objeto como entidad en sí, olvidándo de qué clase es.

Es que los simbolos y el resto de objetos no tienen relacion desde el
punto de vista del programador[*]. Si los piensas vinculados a
variables, metodos, etc. entonces lo mezclas un poco.

Para separar las cosas, un simbolo es una instancia de la clase
Symbol. Como tal tiene su propio object_id, responde a metodos, y
tiene las caracteristicas que lo diferencian de las cadenas que
explico Raul. Y poco mas, hay que pensarlos como una cadena modulo
algunos detalles.

Ciertamente se pueden usar simbolos en las llamadas a algunos metodos
de la API de metaprogramacion:

1.method(:abs) # -> #<Method: Fixnum#abs>
@a = 1; instance_variable_get(:@a) # -> 1

pero esto es asi tan solo porque un simbolo sirve para representar un
nombre, lo mismo sirve una cadena:

1.method(“abs”) # -> #<Method: Fixnum#abs>
@a = 1; instance_variable_get("@a") # -> 1

– fxn

[*] Internamente el interprete usa simbolos para referirse a
variables, metodos, y constantes. Pero ese es un detalle de
implementacion que no forma parte del lenguaje y el programador no ve.

Genial,

me ha quedado mucho más claro.

Gracias Xavier!

Perdón, me he expresado un poco mal: los dos puntos se utilizan para
referirse al objeto como entidad en sí, olvidándo de qué clase es.

Ejemplo:

def foo
puts ‘hola’
end

a = []
a << foo
hola
=> [nil]

es decir, a es [nil] y se ha ejecutado la
función
Sin embargo, si lo hacemos con :foo la cosa cambia:

a << :foo
=> [nil, :foo]

y no se ejecuta nada.

A eso me refiero a tratarlo como una entidad independiente de la
clase. Yo lo veo como la forma universal de acceder a un objeto: sirve
para cualquier clase de objeto y es independiente de ella.

No sé si me he explicado peor aún :S

A mi tb me ha quedado mucho mas claro, gracias a todos!

Inicio del mensaje reenviado:

me ha quedado mucho más claro.

Ciertamente se pueden usar simbolos en las llamadas a algunos metodos

[email protected]
http://lists.simplelogica.net/mailman/listinfo/ror-es
Alberto L.
[email protected]
09-94777312