В Ruby Integer === 5 возвращается true. Аналогично String === "karthik" возвращает true.
Однако 5 === Integer возвращает false. И "karthik" === String.
Почему оператор не коммутативен?
3 Оператор Equals или Equ Equality
Ответ 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.