👻
【bugs.ruby Advent Calender】警告が無効な場合に Warning.warn が呼び出されなくなる【13日目】
bugs.ruby Advent Calender 13日目の記事です。
これはなに
今年1年間通してみてきた bugs.ruby のチケットの中から気になったものを1つずつ取り上げていく Advent Calender です。
取り上げるチケットは基本的にこのブログで取り上げたものになります。
記事のまとめは ここを参照 してください。
[Bug #20573] Warning.warn shouldn't be called for disabled warnings
例えば以下のような Ruby のコードを -W
付きで実行すると警告が出力されます。
def get_var
# warning: variable $= is no longer effective
$=
end
get_var
この警告は deprecated
をカテゴリとして出力されるんですがこのときに Warning#[]=
でカテゴリごとに警告が出ないように制御することができます。
# deprecated な警告は出力されないように制御できる
Warning[:deprecated] = false
def get_var
# warning: variable $= is no longer effective
$=
end
get_var
この挙動を踏まえた上で Warning.warn
を説明するんですが Warning.warn
は内部で警告を出力する際に呼ばれるメソッドになります。
このメソッドを書き換えることで警告の内容を変えたりすることができます。
module Warning
# 警告が出力される際にこのメソッドが呼び出される
def self.warn(message, category:)
pp category => message
end
end
def get_var
$=
end
get_var
__END__
output:
{:deprecated=>"/tmp/vofzcA0/16:8: warning: variable $= is no longer effective\n"}
このチケットは Warning.warn
が Warning[:deprecated] = false
のときに呼び出されないようにするチケットになっています。
このメソッドを呼び出さないようにすることでパフォーマンスが向上するみたいですね。
このチケットではその変更が受け入れられて Warning#[]
に false
が設定されている警告のカテゴリは Ruby 3.4 からは内部で Warning.warn
が呼びされなくなりました。
module Warning
def self.warn(message, category:)
pp category => message
end
end
def get_var
$=
end
# deprecated の警告が無効な場合は deprecated の Warning#warn は呼び出されない
pp Warning[:deprecated] # => false
get_var
# Ruby 3.3 => output: {:deprecated=>"/tmp/vlhK9hI/25:8: warning: variable $= is no longer effective\n"}
# Ruby 3.4 => output: なし
# deprecated の警告が有効な場合は deprecated の Warning#warn が呼び出される
Warning[:deprecated] = true
pp Warning[:deprecated] # => true
get_var
# Ruby 3.3 => output: {:deprecated=>"/tmp/vlhK9hI/25:8: warning: variable $= is no longer effective\n"}
# Ruby 3.4 => output: {:deprecated=>"/tmp/vlhK9hI/25:8: warning: variable $= is no longer effective\n"}
それはそうと思いつつ一応非互換な変更になるのでご注意ください。
Discussion