Tech Racho エンジニアの「?」を「!」に。
  • 開発

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 $VERBOSEtrue
-W1   効果なし($VERBOSEfalseのまま)
-W0   $VERBOSEnil
--verbose   $VERBOSEtrue
引数がない場合はRubyを終了
-v   $VERBOSEtrue
Rubyバージョンも出力
引数がない場合はRubyを終了
--debug -d $DEBUGtrue
$VERBOSEtrue

面白いのは、-v--versionのショートカットであると同時に--verboseのショートカットでもあるという点です。

デバッグモードがインタープリタに及ぼす効果

verbosityモード

$VERBOSE 効果
truefalsenilは不可) Kernel#warnSTDERRに出力
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をオンにします。

関連記事

Ruby: 4種類の同等性比較: equal?/eql?/==/===(翻訳)

Ruby: マジックコメントのさまざまな利用法(翻訳)


  1. 自動で設定される 
  2. デフォルト 

CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。