Каково ожидаемое поведение применения оператора сопоставления Ruby к nil
?
В частности, что должно произойти с переменными захвата и почему?
Этот код
"a1c" =~ /.*(\d).*/
puts $1
nil =~ /.*(\d).*/
puts $1
puts $1.nil?
Производит этот результат:
1
1
false
Насколько я понимаю, неудачное совпадение сбрасывает все переменные захвата на nil
. Если это так, то почему $1
порог 1 после попытки совпадения с nil
?
(Я пытался найти документацию, объясняющую ожидаемое поведение, но мои навыки работы с Google подвели меня.)
🤔 А знаете ли вы, что...
В Ruby все является объектом, включая числа и функции.
Дело в том, что NilClass#=~
не может не совпадать. Он всегда возвращает nil
.
Цитата из документов:
nil =~ other → nil
Сопоставление с фиктивным образцом — всегда возвращает ноль.
Глядя на его исходный код, этот метод чрезвычайно прост и ничего не делает, кроме как возвращает nil
:
static VALUE
nil_match(VALUE obj1, VALUE obj2)
{
return Qnil;
}
Эта беседа в системе отслеживания проблем Ruby может быть актуальна и в этом контексте.
В Ruby < 3.2.0 NilClass#=~
фактически реализуется своим родительским классом Object
в Object#=~ . Это резервный метод, который может быть переопределен подклассами Object
, такими как String
или Regexp
. Метод Object#=~
устарел в Ruby 2.6.0 и окончательно удален в Ruby 3.2.0. Эти версии реализуют NilClass#=~ напрямую.
Базовый Object#=~
соотв. NilClass#=~
сам по себе не выполняет сопоставление, а просто возвращает nil
без установки/сброса каких-либо глобальных магических переменных. Это приводит к тому, что метод доступен для всех объектов, но выполняет значимое действие только с объектами, которые реализуют переопределенный метод.