概要
原著者の許諾を得て翻訳・公開いたします。
- 英語記事: Idiosyncratic Ruby: Ruby, Can You Speak Louder?
- 原文公開日: 2018/05/06
- 著者: Jan Lelis
- サイト: Idiosyncratic Ruby
日本語タイトルは内容に即したものにしました。
Ruby: デバッグモードを使い分ける(翻訳)
Rubyのデバッグモードをオンにする方法はいくつかあり、ライブラリの作者が興味のある人向けに詳細な情報を出力することもできます。しかし残念なことにRubyのデバッグモードは複数あるのです。いつどれを使うのがよいのでしょうか?
次のコードで考えてみましょう。
def production_method
puts "I am doing the right thing part 1"
# @aに一番関心が寄せられている
puts "I am doing the right thing part 2"
end
ここでグローバルな$DEBUG変数にクエリをかける手があります。これはRubyインタプリタ開始時点でオン/オフできます。
def production_method
puts "I am doing the right thing part 1"
$stderr.puts "@a is now: #{@a}" if $DEBUG
puts "I am doing the right thing part 2"
end
しかしこれが最善手なのでしょうか?次でもよいかもしれません。
$stderr.puts "@a is now: #{@a}" if $VERBOSE
または以下の方法も考えられます。
$stderr.puts "@a is now: #{@a}" if Library.debug_mode?
あるいは次はどうでしょうか。
warn "@a is now: #{@a}"
Rubyはこの点で少しばかり風変わりで、「もっと情報を出して欲しい」というシグナルを伝える標準的な方法がありません。Rubyには「debugモード」と「verbosityモード」という2つのグローバルなデバッグモードがあり、それぞれの振る舞いは異なります。Ruby内部では、現在のデバッグモードのステートは2つのグローバル変数から得られます。
グローバルなデバッグステート
それぞれのモードが取れるステートを以下の表に示します。
| 変数 | 値 | CLI変数のミラーリング1 | 意味 |
|---|---|---|---|
$DEBUG |
true |
$-d == true |
debugモード有効 |
$DEBUG |
false2 |
$-d == false |
debugモード無効 |
$VERBOSE |
true |
$-v == true$-w == true$-W == 2 |
verbosityモード有効 |
$VERBOSE |
false2 |
$-v == false$-w == false$-W == 1 |
verbosityモード「中」 |
$VERBOSE |
nil |
$-v == nil$-w == nil$-W == 0 |
verbosityモード「無」 |
verbosityモードは$VERBOSE == falseの場合と$VERBOSE == nilの場合で異なっていることにご注意ください。
さらに追伸: $DEBUGは任意の値に変更できますが、$VERBOSEはそうではありません。$VERBOSEに意味のない値を設定すると単にtrueに設定されます。
次は、デバッグモードの場合に有効なコマンドラインオプションのリストです。
デバッグモードで使えるコマンドラインオプション
| オプション | エイリアス | 効果 |
|---|---|---|
-W2 |
-W, -w |
$VERBOSE→true |
-W1 |
効果なし($VERBOSEはfalseのまま) |
|
-W0 |
$VERBOSE→nil |
|
--verbose |
$VERBOSE→true引数がない場合はRubyを終了 |
|
-v |
$VERBOSE→trueRubyバージョンも出力 引数がない場合はRubyを終了 |
|
--debug |
-d |
$DEBUG→true$VERBOSE→true |
面白いのは、-vが--versionのショートカットであると同時に--verboseのショートカットでもあるという点です。
デバッグモードがインタープリタに及ぼす効果
verbosityモード
$VERBOSE |
効果 |
|---|---|
trueかfalse(nilは不可) |
Kernel#warnをSTDERRに出力 |
true |
インタプリタのレベル1 warningを出力(ハッシュキー重複など) |
true |
インタプリタのレベル2 warningを出力(メソッド再定義など) |
debugモード
$DEBUG |
効果 |
|---|---|
true |
例外の拡張レポートをオンにする。例はこの記事を参照。Thread.abort_on_exceptionもオンになる |
ベストプラクティス
$VERBOSEの$DEBUGのどちらも使わず、標準ライブラリのロガーや他のロギングgemなどのカスタムログ出力を用います。グローバルなデバッグモードに頼るよりこの方が楽です。
レベル2インタプリタwarningを見たいなら$VERBOSE = trueを使います。
拡張例外レポートをオンにしたいなら$DEBUG = trueを使うかThread.abort_on_exceptionをオンにします。