3 Оператор Equals или Equ Equality

В Ruby Integer === 5 возвращается true. Аналогично String === "karthik" возвращает true.
Однако 5 === Integer возвращает false. И "karthik" === String.
Почему оператор не коммутативен?

Ответ 1

Простой ответ: потому что это не имеет смысла. Связь, описываемая оператором, не является коммутативной, почему оператор должен быть?

Просто посмотрите на свои примеры: 5 - это Integer. Но есть Integer a 5? Что это значит?

=== - оператор предположения о сужении, а предположение не коммутирует.

Тот факт, что оператор случайного предположения использует равные знаки, и что его обычно называют тройным равным, оператор threequals или case equality ужасно неудачен, поскольку он не только абсолютно не связан с равенством, но и не соответствует многим законам, которые соответствуют равенству, таким как транзитивность и, как вы упомянули, коммутативность.

Для большей части моего разговора о === см.

Ответ 2

Одна очень простая причина заключается в том, что отношения is_a? для классов просто не могут быть коммутативными. Рассмотрим случай, когда оба операнда являются классами:

Class === String

Это вернет true, потому что String.is_a?(Class). Однако String === Class вернет false, потому что Class.is_a?(String) является ложным и, конечно, как и должно быть.

Другая причина заключается в том, что семантика === зависит от ее левого операнда. Это снова имеет две причины: а) в рубине семантика всегда зависит от левого операнда, поскольку левый операнд является получателем вызова метода, и b) он полезен, поэтому вы можете использовать, например, классы, диапазоны и регулярное выражение в аргументе case с предполагаемой семантикой.

Ответ 3

Многие операторы не являются коммутативными.

=== называется оператором равенства случая, потому что он вызывается, когда ветвление является случаем.

Хорошо и полезно, чтобы:

foo = 42
case foo
when Integer
  # branches here
when String
  # etc...
end

Было бы не очень полезно, если

foo = Integer
case foo
when 42
# would branch here??
when 666
# etc...
end

Обратите внимание, что в Ruby 1.9 оператор === на Proc/lambda вызовет это Proc:

divisible_by_three = ->(x){x % 3 == 0}
divisible_by_three === 42 # => true

Опять же, очень полезно в инструкции case, но не так много в обратном порядке.

Ответ 4

ему нужно реализовать case-при сравнении

Нормально иметь некоммутативные операторы.

/ - % [] . -> ^ << >> < <= > >= && || = += -= ,

И как это бывает, === существует частично как оператор case-when. Это довольно сложное в Ruby, и это не могло быть так, если бы его пришлось упростить до коммутативного op.