😸

[Bug #19932] 正規表現の o オプションの挙動に関するチケット

2024/05/03に公開

[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"]
def letters
  /[A-Z][a-z]/
end

words = %w[abc def xyz]
words.each {|word|
  # o オプションがある場合は letters メソッドは1度しか呼ばれない
  word.match(/\A[#{letters}]+\z/o)
}
  • この挙動自体はドキュメント化されているので期待する挙動ではあるみたい
  • とはいえ気持ちとしてはメソッド呼び出し毎に生成されてほしいよなあ…
GitHubで編集を提案

Discussion