tutorial - === vs.== en Ruby
ruby wikipedia (3)
Dato ===
, ===
también se usa para hacer coincidir excepciones en el rescue
Aquí hay un ejemplo
class Example
def self.===(exception)
puts "Triple equals has been called."
true
end
end
raise rescue Example
# => prints "Triple equals has been called."
# => no exception raised
Esto se usa para hacer coincidir los errores del sistema.
SystemCallError.===
se ha definido para devolver true cuando los dos tienen el mismo error. Con este sistema, los errores de llamada con el mismo número de error, como Errno::EAGAIN
y Errno::EWOULDBLOCK
, se pueden rescatar enumerando solo uno de ellos.
En Ruby, ¿cuál es la diferencia entre == y ===? El RDoc dice
Igualdad de caso: para el objeto de clase, efectivamente es lo mismo que llamar a # ==, pero normalmente los anulan los descendientes para proporcionar una semántica significativa en las sentencias de caso.
¿Es #==
lo mismo que ==
? ¿Podría darnos un ejemplo de cuándo / cómo se usa en las declaraciones de casos?
Los dos realmente no tienen nada que ver el uno con el otro. En particular, #==
es el operador de igualdad y #===
tiene absolutamente nada con la igualdad. Personalmente, me parece bastante desafortunado que #===
vea tan similar a #==
, use el signo igual y a menudo se lo llame operador de igualdad de casos , operador de triple igual o operador de tres puntos cuando realmente no tiene nada que ver con la igualdad.
Llamo a #===
el operador de subsunción de casos (es lo mejor que se me ocurre, estoy abierto a sugerencias, especialmente de hablantes nativos de inglés).
La mejor manera de describir a === b
es "si tengo un cajón etiquetado a
, ¿tiene sentido poner b
en él?"
Entonces, por ejemplo, Module#===
prueba si b.is_a?(a)
. Si tiene Integer === 2
, ¿tiene sentido poner 2
en una casilla etiquetada Integer
? Sí, lo hace. ¿Qué pasa con Integer === ''hello''
? Obviamente no.
Otro ejemplo es Regexp#===
. Prueba para un partido. ¿Tiene sentido poner ''hello''
en una caja etiquetada /el+/
? Sí, lo hace.
Para colecciones tales como rangos, Range#===
se define como una prueba de membresía: tiene sentido poner un elemento en una caja etiquetada con una colección si ese elemento está en la colección.
Entonces, eso es lo que #===
hace: prueba si el argumento puede ser subsumido bajo el receptor.
¿Qué tiene eso que ver con las expresiones de case
? Sencillo:
case foo
when bar
baz
end
es lo mismo que
if bar === foo
baz
end
Sí, por #==
los documentos significan "el método de instancia ==
del objeto actual".
===
se usa en declaraciones de casos 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 definen su propio ===
son Range (para actuar como include?
), Class (para actuar como obj.is_a?(klass)
) y Regexp
(para actuar como =~
excepto que devuelve un booleano). Algunas clases que no definen su propio ===
son las clases numéricas y String.
Asi que
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