2022/03/31 今回の気になった bugs.ruby のチケット
今週は正規表現マッチするときのタイムアウトを導入するチケットがマージされました。
[Feature #17837] Add support for Regexp timeouts
- 正規表現を比較する時にタイムアウトの概念を導入するチケット
- 色々と議論があったが最終的にはタイムアウトの時間を制御する
Regexp.timeout
Regexp.timeout=
が追加された Regexp.timeout
にタイムアウトする時刻(秒)を設定する事で『正規表現を比較する時に設定したタイムアウト秒を越えると例外が発生する』ようになる- デフォルトだと
nil
になっておりnil
だと例外は発生しない
- デフォルトだと
# デフォルトだと nil pp Regexp.timeout # => nil # この場合はタイムアウトしない /A(B|C+)+D/ =~ "A" + "C" * 28 + "X" # タイムアウトする時刻を設定する事ができる Regexp.timeout = 0.1 pp Regexp.timeout # => 0.1 # 正規表現の比較に 0.1秒以上かかると例外が発生する begin /A(B|C+)+D/ =~ "A" + "C" * 28 + "X" rescue => e pp e # => #<Regexp::TimeoutError: regexp match timeout> end
- また
Regexp.new
やRegexp.compile
もキーワード引数timeout:
を受け取るようになたt
# デフォルトだと timeout: nil regexp = Regexp.new("A(B|C+)+D") regexp =~ "A" + "C" * 28 + "X" # 正規表現ごとに個別に timeout を設定することができる regexp2 = Regexp.new("A(B|C+)+D", timeout: 0.5) begin regexp2 =~ "A" + "C" * 28 + "X" rescue => e pp e # => #<Regexp::TimeoutError: regexp match timeout> end
[Feature #12655] Accessing the method visibility
- メソッドの可視性の情報として『
[:public, :protected, :private, :undefined, :overridden]
を取得したい』という要望のチケット :undefined
の情報を取得する手段としてModule#undefined_instance_methods
が新しく追加される予定- PR: https://github.com/ruby/ruby/pull/5733
- まだマージはされていないが matz は accept 済み
class Super def hoge end end class Sub undef hoge end pp Sub.undefined_instance_methods # => [:hoge]
[Feature #15357] Proc#parameters returns incomplete type information
- 以下のようにブロックの引数で『オプショナル引数でないのに
Proc#parameters
で:opt
になる』のは正しくないんじゃないか、というバグ報告
# これは b がオプショナル引数 pr = proc { |a, b = 2| [a,b] } # しかし Proc#parameters は a もオプショナル引数として情報を返す p pr.parameters # => [[:opt, :a], [:opt, :b]] # 同様に以下のような場合も b もオプショナル引数として情報が返ってくる pr = proc { |a = 1, b| [a,b] } p pr.parameters # => [[:opt, :a], [:opt, :b]]
- これは
proc
の引数は全てオプショナル引数として定義されているためである
# オプショナル引数として定義していない a に引数を渡さなくてもエラーにはならない pr = proc { |a, b = 2| [a,b] } p pr.call # => [nil, 2] # こちらも同様 pr = proc { |a = 1, b| [a,b] } p pr.call # => [1, nil]
- なので報告されたコード自体は意図する挙動になっている
- ちなみに
lambda
の場合は必須引数として返ってくる
pr = lambda{|a, b=2| [a,b] } p pr.parameters # => [[:req, :a], [:opt, :b]] pr = lambda{|a=1, b| [a,b] } p pr.parameters # => [[:opt, :a], [:req, :b]]
- また、このように
lambda
であるようにパラメータ情報を受け取る手段としてProc#parameters
にlambda: false
キーワード引数が追加された- これは既に Ruby 3.2 で対応済み
pr = proc{|a, b=2| [a,b] } p pr.parameters # => [[:opt, :a], [:opt, :b]] p pr.parameters(lambda: true) # => [[:req, :a], [:opt, :b]] pr = proc{|a=1, b| [a,b] } p pr.parameters # => [[:opt, :a], [:opt, :b]] p pr.parameters(lambda: true) # => [[:opt, :a], [:req, :b]]