=== и == в Ruby
в Ruby, в чем разница между == и ===? Элемент RDoc говорит
Case Equality - для объекта класса, фактически то же самое, что и вызов #==, но, как правило, переопределяется потомки, чтобы обеспечить значимый семантика в операторах case.
и #==
то же, что и ==
? А не могли бы вы привести пример, когда/как это используется в случае заявления?
3 ответа:
двое действительно не имеют ничего общего друг с другом. В частности,
#==
оператор равенства и#===
не имеет абсолютно ничего общего с равенством. Лично мне очень жаль, что#===
выглядит так, как#==
, использует знак равенства и часто называется случае оператор равенства,triple equals operator или оператор threequals, когда он действительно не имеет ничего общего с равенством.я называю
#===
the case subsumption operator (это лучшее, что я мог придумать, я открыт для предложений, особенно от носителей английского языка).лучший способ описать
a === b
"если у меня есть ящик с надписьюa
, есть ли смысл ставитьb
в нем?"так, например,
Module#===
проверяет, является лиb.is_a?(a)
. Если у вас естьInteger === 2
, есть ли смысл ставить2
в полеInteger
? Да, это так. А как жеInteger === 'hello'
? Очевидно, нет.другой пример:
Regexp#===
. Он проверяет на соответствие. Имеет ли смысл ставить'hello'
в поле/el+/
? Да, это так.для коллекций, таких как диапазоны,
Range#===
определяется как тест членства: имеет смысл поместить элемент в поле, помеченное коллекцией, если этот элемент находится в коллекции.вот так
#===
does: он проверяет, может ли аргумент быть отнесен к категории приемник.какое это имеет отношение к с
case
выражения? Просто:case foo when bar baz end
это то же самое, что
if bar === foo baz end
да,
#==
документы означают " метод экземпляра==
текущего объекта".
===
используется в операторах case как таковых:case obj when x foo when y bar end
это то же самое, что
if x === obj foo elsif y === obj bar end
некоторые классы, которые определяют свои собственные
===
диапазон (чтобы действовать какinclude?
), класс (действовать какobj.is_a?(klass)
) иRegexp
(действовать как=~
кроме возврата логического значения). Некоторые классы, которые не определяют свои собственные===
числовые классы и Строка.так
case x when 0 puts "Lots" when Numeric puts(100.0 / x) when /^\d+$/ puts(100.0 / x.to_f) default raise ArgumentError, "x is not a number or numeric string" end
это то же самое, что
if 0 == x puts "Lots" elsif x.is_a? Numeric puts(100.0 / x) elsif x =~ /^\d+$/ puts(100.0 / x.to_f) else raise ArgumentError, "x is not a number or numeric string" end
забавный факт,
===
также используется для сопоставления исключений вrescue
вот пример
class Example def self.===(exception) puts "Triple equals has been called." true end end raise rescue Example # => prints "Triple equals has been called." # => no exception raised
это используется для сопоставления системных ошибок.
SystemCallError.===
было определено, чтобы вернуть true, когда два имеют одинаковый errno. При этом система вызывает ошибки с одинаковым номером ошибки, напримерErrno::EAGAIN
иErrno::EWOULDBLOCK
, оба могут быть спасены, перечисляя только один из них.