为什么 =~ 运算符只是有时有副作用?

发布于 2024-11-10 02:21:08 字数 907 浏览 3 评论 0原文

我注意到 Ruby/Oniguruma 中的副作用仅出现在 4 个看似等效的语句中的 1 个中。为什么变量 day 定义在 009 中,而不是在 003005007 中代码>?

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 中的行为。

I've noticed a side effect in Ruby/Oniguruma that is only present in 1 out of 4 seemingly equivalent statements. Why is the variable day defined in 009, but not in 003, 005 or 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: It's the same regex and the same string in all four cases.

nb#2: I've verified the behavior in MS Windows and Ubuntu Linux.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓬勃野心 2024-11-17 02:21:08

当您调用 "24:12" =~ r 时,您实际上调用的是 "24:12".=~(r)。因此, String#=~ 仅返回匹配开始的位置,或者如果没有匹配则为零。

但是当你调用 /(?\d\d):(?\d\d)/ =~ "24:12" 你实际上调用 Regexp#=~

正如文档所说

如果 =~ 与正则表达式文字一起使用
具有命名捕获、捕获字符串
(或nil)被分配给本地
由捕获名称命名的变量。

003 怎么样:

如果出现以下情况,则不会发生分配
正则表达式不是文字。

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

如果出现以下情况,则不会发生分配
正则表达式位于右侧。
“x=y”=~
/(?\w+)\s*=\s*(?\w+)/
p
lhs, rhs # 未定义的局部变量

When you call "24:12" =~ r you actually call "24:12".=~(r). So, String#=~ just returns the position the match starts, or nil if there is no match.

But when you call /(?<day>\d\d):(?<mon>\d\d)/ =~ "24:12" you actually call Regexp#=~

And as the documentation says

If =~ is used with a regexp literal
with named captures, captured strings
(or nil) is assigned to local
variables named by the capture names.

what about 003:

The assignment is not occur if the
regexp is not a literal.

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

and

The assignment is not occur if the
regexp is placed at right hand side.
" x = y " =~
/(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/
p
lhs, rhs # undefined local variable

鹊巢 2024-11-17 02:21:08

我相信 003 不受支持,因为它在 Rubyland 中是一个完整的 Regexp 对象,可能具有重写方法等。这使得分配的局部变量的范围变得更加复杂。

I believe 003 isn't supported because it's a full blown Regexp object in Rubyland at that point, possibly with overridden methods and such. That makes the scope of assigned locals a lot more complicated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文