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"

注意事項 1: 4 つのケースすべてで同じ正規表現と同じ文字列です。

注 2: MS Windows と Ubuntu Linux での動作を確認しました。

4

2 に答える 2

13

あなたが呼び出すとき、あなた"24:12" =~ rは実際に呼び出します"24:12".=~(r)。したがって、String#=~は、一致が開始された位置を返すか、一致がない場合は nil を返します。

しかし、呼び出すときは/(?<day>\d\d):(?<mon>\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 " =~ /(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/
p lhs, rhs # 未定義のローカル変数

于 2011-05-25T12:49:31.890 に答える
1

003 はサポートされていないと思います。これは、その時点で Rubyland の本格的な Regexp オブジェクトであり、メソッドがオーバーライドされている可能性があるためです。これにより、割り当てられたローカルのスコープがより複雑になります。

于 2011-05-25T13:52:27.670 に答える