2011-05-25 28 views
12

我注意到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中的行为。

+2

注意:虽然这不是这种情况,但在使用IRb中的局部变量时应该小心。由于在IRB中评估代码的方式,它们在IRB中的行为可能与脚本中的行为略有不同。总是写脚本来确认。 – 2011-05-25 15:25:59

+0

好点,Jörg。 – 2011-05-25 16:26:11

回答

13

当您拨打"24:12" =~ r时,实际上您会拨打"24:12".=~(r)。因此,String#=~只是返回比赛开始的位置,如果没有匹配,则为零。

可是,当你调用/(?<day>\d\d):(?<mon>\d\d)/ =~ "24:12"你居然叫Regexp#=~

而作为文件说

如果=〜用于与文字 名为捕获正则表达式,捕获串 (或无)是分配给当地的 由捕获名称命名的变量。

003什么:

如果 正则表达式是不是文字没有发生分配。如果正则表达式 放置在右手侧不发生

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

分配。
“X = Y”=〜 /(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/
p LHS,RHS#未定义的局部变量

+0

谢谢纳什。一个非常好的答案。但是,你也可以在问题中解释'003' - 即编译的正则表达式(而不是正则表达式)接收到'='消息,并且它不分配本地变量。 – 2011-05-25 12:59:47

+0

不客气!查看更新。 – 2011-05-25 13:04:39

+1

“已捕获的字符串已分配...”,“分配未发生......”?奇怪的语法... – 2011-05-25 14:16:05

1

我认为003不支持,因为它是一个完全成熟的RegExp对象在Rubyland在这一点上,可能与重写的方法等。这使得分配的当地人的范围变得更加复杂。

+0

谢谢,詹姆斯。我对Ruby创作者的意图有了另一个想法,但你可能是对的,这是一个技术问题。 – 2011-05-25 14:53:31

相关问题