Подтвердить что ты не робот

Почему оператор = ~ только иногда имеет побочные эффекты?

Я заметил побочный эффект в Ruby/Oniguruma, который присутствует только в 1 из 4, казалось бы, эквивалентных утверждений. Почему переменная day определена в 009, но не в 003, 005 или 007?

irb(main):001:0> r = /(?<day>\d\d):(?<mon>\d\d)/
=> /(?<day>\d\d):(?<mon>\d\d)/

irb(main):002:0> r =~ "24:12"
=> 0
irb(main):003:0> day
NameError: undefined local variable or method `day' 

irb(main):004:0> "24:12" =~ r
=> 0
irb(main):005:0> day
NameError: undefined local variable or method `day'


irb(main):006:0> "24:12" =~ /(?<day>\d\d):(?<mon>\d\d)/
=> 0
irb(main):007:0> day
NameError: undefined local variable or method `day'


irb(main):008:0> /(?<day>\d\d):(?<mon>\d\d)/ =~ "24:12"
=> 0
irb(main):009:0> day
=> "24"

nb # 1: Это одно и то же регулярное выражение и одна и та же строка во всех четырех случаях.

nb # 2: Я проверил поведение в MS Windows и Ubuntu Linux.

4b9b3361

Ответ 1

Когда вы вызываете "24:12" =~ r, вы на самом деле вызываете "24:12".=~(r). Итак, String # = ~ просто возвращает позицию, с которой начинается совпадение, или nil, если нет совпадения.

Но когда вы вызываете /(?<day>\d\d):(?<mon>\d\d)/ =~ "24:12", вы на самом деле вызываете Regexp # = ~

И как говорится в документации

If = ~ используется с литералом regexp с именованными захватами, захваченные строки (или nil) присваивается локальному переменные, названные именами захвата.

как насчет 003:

Назначение не возникает, если regexp не является литералом.

   re = /(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/
   re =~ "  x = y  "
   p lhs    # undefined local variable
   p rhs    # undefined local variable

и

Назначение не возникает, если regexp помещается с правой стороны.
"x = y" = ~ /(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/
п lhs, rhs # undefined Локальная переменная

Ответ 2

Я считаю, что 003 не поддерживается, потому что он полностью переработанный объект Regexp в Rubyland в этот момент, возможно, с переопределенными методами и т.д. Это делает объем назначенных локальных жителей намного сложнее.