¿Qué es el operador de dos puntos en Ruby?

Resuelto LuxuryMode asked hace 13 años • 9 respuestas

Cuando digo { :bla => 1, :bloop => 2 }, ¿qué hace exactamente :? Leí en alguna parte que es similar a una cadena, pero de alguna manera es un símbolo.

No tengo muy claro el concepto, ¿alguien podría iluminarme?

LuxuryMode avatar Jun 14 '11 07:06 LuxuryMode
Aceptado

:fooes un símbolo llamado "foo". Los símbolos tienen la característica distintiva de que dos símbolos cualesquiera con el mismo nombre serán idénticos:

"foo".equal? "foo"  # false
:foo.equal? :foo    # true

Esto hace que comparar dos símbolos sea realmente rápido (ya que solo se trata de una comparación de puntero, en lugar de comparar todos los caracteres como lo haría en una cadena), además no tendrá millones de copias del mismo símbolo flotando.

Además, a diferencia de las cadenas, los símbolos son inmutables.

C. K. Young avatar Jun 14 '2011 00:06 C. K. Young

Solo para demostrar algunas de las cosas mencionadas en las respuestas:

require 'benchmark'

n = 1_000_000

print '"foo".equal? "foo" -> ', ("foo".equal? "foo"), "\n"
print '"foo" == "foo"     -> ', ("foo" == "foo"    ), "\n"
print ':foo.equal? :foo   -> ', (:foo.equal? :foo  ), "\n"
print ':foo == :foo       -> ', (:foo == :foo      ), "\n"

Benchmark.bm(10) do |b|
  b.report('string')     { n.times { "foo".equal? "foo" }}
  b.report('str == str') { n.times { "foo" == "foo"     }}
  b.report('symbol')     { n.times { :foo.equal? :foo   }}
  b.report('sym == sym') { n.times { :foo == :foo       }}
end

Al ejecutarlo se obtiene:

"foo".equal? "foo" -> false
"foo" == "foo"     -> true
:foo.equal? :foo   -> true
:foo == :foo       -> true

Entonces, comparar una cadena con otra usando equal?falla porque son objetos diferentes, incluso si tienen el mismo contenido. ==compara el contenido y las comprobaciones equivalentes con símbolos son mucho más rápidas.

                 user     system      total        real
string       0.370000   0.000000   0.370000 (  0.371700)
str == str   0.330000   0.000000   0.330000 (  0.326368)
symbol       0.170000   0.000000   0.170000 (  0.174641)
sym == sym   0.180000   0.000000   0.180000 (  0.179374)

Ambas pruebas de símbolos son básicamente iguales en cuanto a velocidad. Después de 1.000.000 de iteraciones, solo hay una diferencia de 0,004733 segundos, por lo que diría que es un lavado entre los cuales usar.

the Tin Man avatar Feb 23 '2013 17:02 the Tin Man

Los símbolos son una forma de representar cadenas y nombres en Ruby.

La principal diferencia entre símbolos y cadenas es que los símbolos del mismo nombre se inicializan y existen en la memoria sólo una vez durante una sesión de Ruby.

Son útiles cuando necesitas usar la misma palabra para representar cosas diferentes.

nunopolonia avatar Jun 14 '2011 00:06 nunopolonia