Возможный дубликат:
=== vs. == в Ruby
Я видел, как он использовался несколько раз в последнее время, но не может понять, что он делает. Может ли кто-нибудь проиллюстрировать, как это работает?
Возможный дубликат:
=== vs. == в Ruby
Я видел, как он использовался несколько раз в последнее время, но не может понять, что он делает. Может ли кто-нибудь проиллюстрировать, как это работает?
Как и любой другой метод в 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
).
Однако для ===
нет ожиданий ни симметрии, ни транзитивности. На самом деле, это очень не дизайн, а не симметричный. Вот почему я не люблю называть это чем-то, что даже отдаленно напоминает равенство. Это также, почему я думаю, это должно было быть названо чем-то еще, как ~~~
или что-то еще.
Спасибо за ваше редактирование Джейкоба, я собирался позвонить вам;) Я все же отправлю пару примеров. Реализация === отличается в зависимости от типа. Например:
(1...3) === 2
=> true
/test/ === "this is a test"
=> true
case 'test'
when /blah/
"Blach"
when /test/
"Test"
else
"Fail"
end
=> "Test"
Stephen, checkout http://ruby-doc.org/docs/ProgrammingRuby/ ( "Pickaxe" ), он должен быть в состоянии помочь вам с такими вопросами, как это в будущее.
В Ruby оператор ===
используется для проверки равенства в выражении when
оператора case
. В других языках это верно.
Насколько я знаю, Ruby не имеет истинных операторов, все они методы, которые вызывают в LHS выражения, передавая в RHS выражения. Так что, действительно, вы можете переопределить любой "оператор", который вы хотите, чтобы ваши классы выполняли все, что вам нужно (аналогично перегрузке оператора на С++).