=== vs == en Ruby

Resuelto Mads Mobæk asked hace 14 años • 3 respuestas

En Ruby, ¿cuál es la diferencia entre == y ===? El RDoc dice

Igualdad de casos: para la clase Objeto, en realidad es lo mismo que llamar a #==, pero normalmente los descendientes lo anulan para proporcionar una semántica significativa en las declaraciones de caso.

Es #==lo mismo que ==? ¿Y podría darnos un ejemplo de cuándo y cómo se utiliza esto en declaraciones de caso?

Mads Mobæk avatar Aug 06 '10 15:08 Mads Mobæk
Aceptado

Los dos realmente no tienen nada que ver el uno con el otro. En particular, #==es el operador de igualdad y #===no tiene absolutamente nada que ver con la igualdad. Personalmente, me parece bastante desafortunado que #===se parezca tanto a #==, use el signo igual y a menudo se le llame operador de igualdad de casos , operador triple igual o operador tres iguales cuando en realidad no tiene nada que ver con la igualdad.

Llamo #===al operador de subsunción de casos (es lo mejor que se me ocurrió, estoy abierto a sugerencias, especialmente de hablantes nativos de inglés).

La mejor manera de describirlo a === bes "si tengo un cajón con la etiqueta a, ¿tiene sentido colocarlo ballí?"

Entonces, por ejemplo, Module#===prueba si b.is_a?(a). Si es así Integer === 2, ¿tiene sentido ponerlo 2en una caja etiquetada Integer? Sí, lo hace. Qué pasa Integer === 'hello'? Obviamente no.

Otro ejemplo es Regexp#===. Prueba una coincidencia. ¿Tiene sentido ponerlo 'hello'en una caja etiquetada /el+/? Sí, lo hace.

Para colecciones como rangos, Range#===se define como una prueba de membresía: tiene sentido colocar un elemento en un cuadro etiquetado con una colección si ese elemento está en la colección.

Entonces, eso es lo que #===hace: prueba si el argumento puede incluirse en el receptor.

¿Qué tiene eso que ver con caselas expresiones? Simple:

case foo
when bar
  baz
end

es lo mismo que

if bar === foo
  baz
end
Jörg W Mittag avatar Aug 06 '2010 09:08 Jörg W Mittag

Sí, #==los documentos significan "el método de instancia ==del objeto actual".

===se utiliza en declaraciones de caso como tales:

case obj
when x
  foo
when y
  bar
end

Es lo mismo que

if x === obj
  foo
elsif y === obj
  bar
end

Algunas clases que se definen ===son Range (actuar como include?), Clase (actuar como obj.is_a?(klass)) y Regexp(actuar como =~excepto devolver un valor booleano). Algunas clases que no se definen ===son las clases numéricas y String.

Entonces

case x
when 0
  puts "Lots"
when Numeric
  puts(100.0 / x)
when /^\d+$/
  puts(100.0 / x.to_f)
default
  raise ArgumentError, "x is not a number or numeric string"
end

es lo mismo que

if 0 == x
  puts "Lots"
elsif x.is_a? Numeric
  puts(100.0 / x)
elsif x =~ /^\d+$/
  puts(100.0 / x.to_f)
else
  raise ArgumentError, "x is not a number or numeric string"
end
sepp2k avatar Aug 06 '2010 08:08 sepp2k