😸
[Bug #19932] 正規表現の o オプションの挙動に関するチケット
[Bug #19932] Regexp o modifier freeze interpolation between method calls
- 正規表現で
o
オプションを指定している時におかしい挙動があったけどこれは意図していますか?というチケット - 例えば次のように引数に依存する形で正規表現を定義している場合
def poc(regexp)
hs = [
'azerty',
'azertyui',
'azertyuiop'
]
out = []
hs.each do |h|
# o オプションなし
out << h if /#{regexp}/.match?('azerty')
end
out
end
# az にマッチする文字列が返ってくる
p poc('az')
# => ["azerty", "azertyui", "azertyuiop"]
# wxc にマッチする文字列が返ってくる
p poc('wxc')
# => []
- 次に
o
オプションがある場合
def poc(regexp)
hs = [
'azerty',
'azertyui',
'azertyuiop'
]
out = []
hs.each do |h|
# o オプションを追加する
out << h if /#{regexp}/o.match?('azerty')
end
out
end
# az にマッチする文字列が返ってくる
# これは同じ
p poc('az')
# => ["azerty", "azertyui", "azertyuiop"]
# wxc ではなくて az にマッチする文字列が返ってくる
p poc('wxc')
# => ["azerty", "azertyui", "azertyuiop"]
- これは
o
オプションがパターン内の #{} の展開を1回限りしかしない。
という挙動になっているのでこうなっている
def letters
/[A-Z][a-z]/
end
words = %w[abc def xyz]
words.each {|word|
# o オプションがある場合は letters メソッドは1度しか呼ばれない
word.match(/\A[#{letters}]+\z/o)
}
- この挙動自体はドキュメント化されているので期待する挙動ではあるみたい
- とはいえ気持ちとしてはメソッド呼び出し毎に生成されてほしいよなあ…
Discussion