Что делает оператор "===" в Ruby?

Возможный дубликат:
=== vs. == в Ruby

Я видел, как он использовался несколько раз в последнее время, но не может понять, что он делает. Может ли кто-нибудь проиллюстрировать, как это работает?

Ответ 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).

Однако для === нет ожиданий ни симметрии, ни транзитивности. На самом деле, это очень не дизайн, а не симметричный. Вот почему я не люблю называть это чем-то, что даже отдаленно напоминает равенство. Это также, почему я думаю, это должно было быть названо чем-то еще, как ~~~ или что-то еще.

Ответ 2

Спасибо за ваше редактирование Джейкоба, я собирался позвонить вам;) Я все же отправлю пару примеров. Реализация === отличается в зависимости от типа. Например:

(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" ), он должен быть в состоянии помочь вам с такими вопросами, как это в будущее.

Ответ 3

В Ruby оператор === используется для проверки равенства в выражении when оператора case. В других языках это верно.

Насколько я знаю, Ruby не имеет истинных операторов, все они методы, которые вызывают в LHS выражения, передавая в RHS выражения. Так что, действительно, вы можете переопределить любой "оператор", который вы хотите, чтобы ваши классы выполняли все, что вам нужно (аналогично перегрузке оператора на С++).