2011-05-25 65 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

相關問題