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. デフォルト 
デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ