Ответ 1
Как и любой другой метод в Ruby (или фактически практически любой объектно-ориентированный язык),
a === b
означает, что любой класс класса a
хочет, чтобы это означало.
Однако, если вы не хотите сбивать с толку своих коллег, соглашение заключается в том, что ===
является оператором субобъекта. В принципе, это логический оператор, который задает вопрос "Если у меня есть ящик с меткой a
, имеет смысл положить b
в этот ящик?"
Альтернативная формулировка: "Если a
описал набор, мог бы b
быть членом этого множества?"
Например:
(1..5) === 3 # => true
(1..5) === 6 # => false
Integer === 42 # => true
Integer === 'fourtytwo' # => false
/ell/ === 'Hello' # => true
/ell/ === 'Foobar' # => false
Основное использование для оператора ===
находится в выражениях case
, так как
case foo
when bar
baz
when quux
flurb
else
blarf
end
переводят на что-то (примерно), например
_temp = foo
if bar === _temp
baz
elsif quux === _temp
flurb
else
blarf
end
Обратите внимание, что если вы хотите найти этот оператор, его обычно называют оператором тройного равенства или оператором трехмерного оператора или оператора равенства. Мне очень не нравятся эти имена, потому что этот оператор абсолютно не имеет никакого отношения к равенству.
В частности, можно было бы ожидать, что равенство будет симметричным: если a
равно b
, то b
лучше также быть равно a
. Кроме того, можно было бы ожидать, что равенство будет транзитивным: если a == b
и b == c
, то a == c
. Хотя на самом деле невозможно гарантировать, что на языке единой рассылки, таком как Ruby, вы должны, по крайней мере, приложить усилия для сохранения этого свойства (например, следуя протоколу coerce
).
Однако для ===
нет ожиданий ни симметрии, ни транзитивности. На самом деле, это очень не дизайн, а не симметричный. Вот почему я не люблю называть это чем-то, что даже отдаленно напоминает равенство. Это также, почему я думаю, это должно было быть названо чем-то еще, как ~~~
или что-то еще.