ruby equality commutativity

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.