ruby::
3 igual o igual que el operador de igualdad (4)
En Ruby Integer === 5
devuelve true
. De manera similar, String === "karthik"
devuelve true
.
Sin embargo, 5 === Integer
devuelve false
. Y "karthik" === String
.
¿Por qué el operador no es conmutativo?
necesita implementar caso-cuando las comparaciones
Es normal tener operadores no conmutativos.
/ - % [] . -> ^ << >> < <= > >= && || = += -= ,
Y, a medida que sucede, ===
existe en parte como el operador de caso cuando . Eso es bastante elaborado en Ruby, y no podría ser así si tuviera que simplificarse a una operación conmutativa.
La respuesta simple es: porque no tiene sentido. La relación que describe el operador no es conmutativa, ¿por qué debería serlo el operador?
Solo mire sus propios ejemplos: 5
es un Integer
. Pero, ¿es Integer
un 5
? ¿Qué significa eso?
===
es el operador de subsunción de caso , y la subsunción no conmuta.
El hecho de que el operador de subsunción de casos use signos iguales y que generalmente se denomina el operador de case equality
, threequals
o case equality
es terriblemente desafortunado, ya que no solo no tiene absolutamente nada que ver con la igualdad, sino que no se ajusta a muchos de ellos. las leyes a las que se ajusta la igualdad, como la transitividad y como usted mencionó conmutatividad.
Para más de mi despotricar sobre ===
ver
- ¿Qué hace el operador
===
en Ruby? -
===
vs.==
en Ruby - ¿Cómo funciona
Integer === 3
?
Muchos operadores no son conmutativos.
El ===
se denomina "operador de igualdad de casos" porque se llama cuando la bifurcación es un caso.
Es agradable y útil que:
foo = 42
case foo
when Integer
# branches here
when String
# etc...
end
No sería muy útil si
foo = Integer
case foo
when 42
# would branch here??
when 666
# etc...
end
Tenga en cuenta que en Ruby 1.9, el operador ===
en un Proc / lambda lo llamará Proc:
divisible_by_three = ->(x){x % 3 == 0}
divisible_by_three === 42 # => true
De nuevo, muy útil en una declaración de case
, pero no mucho en el orden inverso.
Una razón muy simple es que el is_a?
La relación para las clases no puede ser conmutativa. Considere el caso donde ambos operandos son clases:
Class === String
Esto devolverá verdadero porque String.is_a?(Class)
. Sin embargo, String === Class
devolverá false, porque Class.is_a?(String)
es false y eso es, por supuesto, como debería ser.
Otra razón es que la semántica de ===
depende de su operando izquierdo. Esto tiene nuevamente dos razones: a) En ruby, la semántica siempre depende del operando izquierdo, porque el operando izquierdo es el receptor de la llamada al método yb) es útil, por lo que puede usar clases, rangos y regexen en un caso Declaración con la semántica pretendida.