В 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.