大阪Ruby会議02で、「Suppress Warnings」というタイトルで登壇しました
speakerdeckよりもGoogle Slideの方が埋め込んだGIF動画が動くのでオススメです。
大阪Ruby会議02でSuppress Warningsというタイトルで登壇させていただきました。 登壇してから気がついたことや、スライドに盛り込めなかったことが沢山あるので、この記事ではそれを補足しようと思います。
「警告のレベル」という表現について
スライド中で「警告のレベル」という表現をしましたが、そういえばこれは一般的な表現ではないなあと気がついたので少し補足です。
今回、「警告のレベル」という表現はRubyの-W
オプションの説明から持ってきました。
-W[level] 冗長モードを三段階のレベルで指定します。それぞれ以下の通りです。
* -W0: 警告を出力しない * -W1: 重要な警告のみ出力(デフォルト) * -W2 or -W: すべての警告を出力する
組み込み変数 $VERBOSE はそれぞれ nil, false, true に設定されます。
https://docs.ruby-lang.org/ja/latest/doc/spec=2frubycmd.html
警告が発生するタイミングについて
Rubyの警告は、その発生タイミングから2種類に分けられます。
1つは構文解析時に発生する警告、もう1つは実行時に発生する警告です。
構文解析時には、コードを実行せずともわかるようなものが警告されます。 例えば「未使用のローカル変数」や「正規表現内の文字クラスの重複」などはコードを実行せずとも警告を出せます。
一方で実行時には、コードを実行しないとわからないようなものが警告されます。
例えば「File.exists?
のような非推奨メソッドの使用」や「未初期化のインスタンス変数へのアクセス」はコードを見ただけでは判断が難しいため、実行時の警告として実装されています。
こちらは基本的にコードが実行される度に警告が表示されるので、時として画面を警告が川のように流れる要因となります。
RuboCopとの違いについて
RuboCopができることは、上記の「構文解析時に発生する警告」と同じです。 また、多くのRubyの警告がRuboCopにもCopとして移植されてます。
また、RuboCopでは偽陽性を許容することで、コードを実行せずともFile.exists?
メソッドの使用に警告を出したりしています。
これは例えば次のようなコードで間違った警告を出してしまうことになります。
class A class File end def foo # ここでは`File`は`A::File`を指すため、警告は出るべきではない。 # Ruby -wは実行時に警告を出すため、警告が出ない。 # ところがRuboCopは構文解析のみで警告を出すため、このコードに対して警告が出てしまう。 File.exists?(x) end end
また、RuboCopはruby -w
のような警告の他にもコーディングスタイルに関する指摘なども行うという違いもありますね。
CFPではRuboCopとの違いについても話すと書いていたのですが、削ってしまいました。
Warning moduleについて
Ruby 2.4から、Warning
というモジュールが追加されました。
全てのRubyの警告はWarning#warn
を呼び出すことで表示されます。
そのため、このメソッドを上書きすることで警告が発生した時の挙動を変えることができます。
例えばwarningというgemを使うと特定のパターンにマッチした警告は無視する、などの操作を行うことが可能です。
y-yagi.tumblr.comRuby 2.7のキーワード引数の警告
mameさんが話していましたね。
個人的には、急いで対応しなくてもpreviewが出るまで待っても良いかなと思っています。
消えた警告について
今まで警告されていたコードが、Rubyのバージョンアップに伴って警告されなくなったものがいくつかあります。
たとえばflip-flopへの警告や「shadowing outer local variable」の警告です。