Рубиновый тройной равный

Скажем, что у меня есть следующий код.

result = if a.is_a?(Class) && a <= Exception
   a.name
elsif ...
elsif ...
end

Я реорганизовал этот код на

case a
when Exception
     a.name
when ...
when ...
end

Правильно ли я понимаю тройное равенство?

Ответ 1

Мы не можем сказать, действительно ли вы получаете === или нет из такого ограниченного примера. Но вот разложение того, что на самом деле происходит при использовании ===, явно или неявно как часть аргумента case/when, например, используемого в примере.

Тройка равная (===) имеет множество различных реализаций, которые зависят от класса левой части. Это действительно просто инфиксная нотация для метода. ===. Это означает, что следующие утверждения идентичны:

a.=== b
a === b

Разница не очень похожа, но это означает, что метод левой стороны === вызывается вместо какого-то магического оператора, определенного на уровне языка, например, ==, но не совсем. Вместо этого === определяется в каждом классе, который его использует, возможно, в унаследованном классе или в Mixin.

Общее определение тройного равенства состоит в том, что оно вернет true, если обе части идентичны или если правая часть содержится в пределах левого.

В случае класса. === операция вернет true, если аргумент является экземпляром класса (или подкласса). В случае, когда левая сторона является регулярным выражением, она возвращает true, когда правая сторона соответствует регулярному выражению.

Когда случай является подразумеваемым ===, который сравнивает переменную case с предложением where, используя ===, так что следующие два оператора дают тот же результат.

case a
when String
  puts "This is a String"
when (1..3)
  puts "A number between 1 and 3"
else
  puts "Unknown"
end

if String === a 
  puts "This is a String"
elsif (1..3) === a
  puts "A number between 1 and 3"
else
  puts "Unknown"
end

Проверьте документацию для типов, которые вы используете в левой части выражения === или в инструкции when, чтобы точно знать, как это работает.

Ответ 2

Я считаю, что в первом примере вы проверяете, является ли a подклассом Exception (исправьте меня, если я ошибаюсь). Второй пример просто проверяет, является ли a экземпляром Exception (эквивалентно a.is_a?(Exception)).