より良い'printf'デバッグ
他の言語: English Español 한국어 Português 中文
最も一般的なデバッグ手法の一つである’printf’ デバッグ は、最初のプログラムを書く際に直感的に学ぶ多くの人々に非常に人気があります。
‘printf’ デバッグは特別なツールがなくても利用できるので非常に手軽です。 何もデバッガーとは何かを知る前に、最初のバグに対処する際には、 プログラムが変数を順番に出力するようにすることで、コンソールでの実行を追うことが自然に思いつきます。

これは最も基本的なデバッグ手法の一つでありながら、経験豊富な開発者も多く使用しています。 それはあらゆる種類の問題、例えば、サブオプティマルルーチン、状態の不一致、マルチスレッドの問題などを調査するのに役立ちます。
既に述べたように、この技術はあなたがIDEなどの特別なツールを使うことを必要としません。 しかし、もしあなたがそれを使っているなら、それはあなたがプログラムの状態をログに記録することでさらに効率的にすることができます。
この記事では IntelliJ IDEA の機能を紹介しています。 他のIDEでは同様の機能が利用可能かどうかは異なります。 他のツールを使用している場合は、そのドキュメンテーションを確認して、これらの機能がそこにも存在するかどうかを確認することを検討してみてください。
LIVEテンプレート
IntelliJ IDEAは、最も一般的なデバッグログパターンのライブテンプレートを提供しています。 デバッグログ用のライブテンプレートを使用するには、対応する省略形を入力し、Tabキーを押します。 IntelliJ IDEA は print 文を生成してキャレットの位置に挿入します。
いくつかの例を見てみましょう。
メソッドのパラメーターの記録
public static BufferedImage recolor(BufferedImage in, BufferedImage mask, int newColor) {
// type 'soutp' here, then press Tab
return null;
}
public static BufferedImage recolor(BufferedImage in, BufferedImage mask, int newColor) {
System.out.println("in = " + in + ", mask = " + mask + ", newColor = " + newColor);
return null;
}
値の記録
public static double coolMethod(double parameter) {
double a = Math.random();
double b = Math.random();
// type 'soutv' here, press Tab, then select the value
return a * b * parameter;
}
public static double coolMethod(double parameter) {
double a = Math.random();
double b = Math.random();
System.out.println("b = " + b);
return a * b * parameter;
}
メソッドのエントリの記録
public static BufferedImage recolor(BufferedImage in, BufferedImage mask, int newColor) {
// type 'soutm' here, then press Tab
return null;
}
public static BufferedImage recolor(BufferedImage in, BufferedImage mask, int newColor) {
System.out.println("ImageUtils.recolor");
return null;
}
ログのブレークポイント
print文を使ったデバッグの欠点の一つは、手動で管理するというオーバーヘッドが発生することです。 それらを素早くオンオフすることはできず、間違ってコミットしたり本番環境で実行したりすることは絶対に避けたいと思うでしょう。
そのため、デバッグ目的で何かをログに記録する必要がある場合、 ログのブレークポイントを使用することを推奨します。これらは管理がはるかに簡単です。


ログのブレークポイントを設定するには、Shiftキーを押しながらガターをクリックします。 通常のブレークポイントと異なり、プログラムの実行は一時停止せず、代わりにログ出力します。
デフォルトでは、プログラムがこの行に到達したことを示すメッセージです。 現在のスタックトレースをログに出力する、 あるいはカスタム表現の結果をログに出力するなど、 ブレークポイントの設定の評価して記録 (Evaluate and log) チェックボックスの近くのオプションを使用することもできます。


何をログに記録するかの表現には注意が必要です。副作用を引き起こすものを評価すると、新たなバグや予期しない挙動を引き起こすことがあります。 また、ホットなコードで使用された場合、 それらはプログラムを大幅に遅くする可能性があります。
ログのブレークポイントが増えてくると、 ブレークポイント (Breakpoints)ダイアログ (実行 (Run) | ブレークポイントの表示 (View Breakpoints))でそれらを把握し、管理することができます:


あなたはそれらのためにカスタムグループを作成することさえできます:


これにより、ブレークポイントを一元的に管理することができます。 例えば、特定のバグに関連するグループを作成し、それを後で保存することができます。 問題が解消されたら、それをオフにします。 そうすれば、問題が再発した場合、全てをゼロから再作成する必要はありません。 単にそのグループを再度オンにします。
頻繁なイベントのログ記録
プログラムの実行中に頻繁に発生するイベントについては、 すべてのイベントを記録することは冗長であるかもしれません。これはコンソールをメッセージで溢れさせるだけでなく、 I/O との多くのやり取りはデバッグセッションを大幅に遅くする可能性があります。


そのようなイベントに対しては、パス数 (Pass count)機能を利用すると便利かもしれません。これはブレークポイント (Breakpoints)ダイアログからアクセスできます。


パス数 (Pass count)を特定の値に設定した後、 対応するブレークポイントはn回目のヒットごとにのみ発火するようになり、ロギングが迷惑をかけないようになります。
まとめ
プリントステートメントを挿入したり、デバッグのためのログのブレークポイントを設定したりするかに関わらず、 現代のツールには、デバッグ体験を向上させる機能があります。 この投稿で、私はこの一連のプロセスをより楽しむためのちょっとしたトリックをあなたが認識していることを確認したかったのです。
ハッピーデバッグ!