バグ発見能力を高める

2019-05-14

本章のあらすじ

  • バグと戦う技術
  • 親切なコードを書くべき理由とその方法

バグと戦う技術

書いているプログラムが大きく複雑になるにつれ、意図通り動かない「バグ」に遭遇する機会も増えてくると思います。そろそろバグと戦う(=デバッグする)ためのさまざまな技術を身につけておきましょう。

エラーメッセージはヒントの宝庫

エラーが出たとき、出ているメッセージもよく読まずに手当たり次第書き換えていませんか?

まずはコード中で赤い波線が出ている箇所を探してみましょう。エラーが起きている場所から何かヒントが得られるかもしれません。上の例なら「ちょうど閉じ括弧があるべき場所だな…」など。

エラーだ…

そして、エラーメッセージを読んでみましょう。翻訳漏れで英語の場合もありますが、単語だけでも拾えれば何か読み取れるかもしれません。上の例なら Missing なので何かが足りない、 bracket なので括弧。つまり括弧が不足しているのではないか…ということが読み取れます。

中には、英語がとても苦手で1㍈もわからないという人がいるかもしれません。そんな人は、エラー右にあるこのボタンを押すとメッセージがコピーできるので、Google翻訳にかけるなりしてみましょう。あるいは、Shiftを押しながらクリックすればそのままWebブラウザーでキーワード検索してくれます。

エラーメッセージはヒントの宝庫です。読み飛ばして焦る前に、一度は目を通して考えてみましょう。

変数の中身を出力してみる: println()

println() を使うと、その時点での変数の中身を、文字としてコンソールに出力できます。

println( 変数 ;
// 変数 ballX の中身をコンソールに出力してみる
println(ballX);

これが変数の中身を確認する一番手軽な手段です。プログラムがうまく動かないときは、まずは変数の値が意図どおりになっているか println() で確認してみるとよいでしょう。

1文ずつ確認する:ステップ実行

Processingに付属している「デバッガ」という機能を使うと、処理を一時停止してそのときの状態を調査できます。

メニューの「デバッグ→デバッガを有効化」で有効化しましょう。

ウィンドウの装いがやや変わりましたね。「Variables」ウィンドウも表示されています。

デバッガでは「ブレークポイント」という機能を使って、プログラムの実行を好きな行で一時停止させることができます。デバッガが有効化された状態で、コードエリア左の行番号をクリックしてください。

クリックしてブレークポイントを設定した

ひし形「◆」がブレークポイントです。このままプログラムを実行すると、ブレークポイントを設定した行に到達した時点で一時停止します。

「▶︎」マークの位置で一時停止した

マークが「▶︎」に変化しており、ここで一時停止しているのがわかります。

「Variables」ウィンドウでは、この一時停止時点での変数の値を一望できます。「Processing」をクリックするとシステム変数も確認できますね。便利…。

一時停止後は、「ステップ」ボタンで1行だけ進めたり、「続行」ボタンでまた次のブレークポイントまで実行させたりできます。

「ステップ」ボタン
「続行」ボタン

プログラムが複雑になってきて、思いどおりに動かなくなってきてから威力を発揮します。役立つ機能があることを頭の隅に入れておきましょう。

親切なコードを書く

親切なコードを書くように心がけると、バグの発生を抑えるのに役立ちます。

インデントを整える

インデント」とは、文の先頭に入っている空白文字による字下げのことです。字下げがバラバラだと、コードの構造が把握しづらくなります。

// インデントばらばら

    if (mouseButton == RIGHT) {
// 次のペンモードに切り替える
   penMode = penMode + 1;

  // 最後のペンモードを超えたら
       if (penMode > 3) {
// 最初に戻す
  penMode = 0;
      }
          }
// インデント整形済み

if (mouseButton == RIGHT) {
  // 次のペンモードに切り替える
  penMode = penMode + 1;

  // 最後のペンモードを超えたら
  if (penMode > 3) {
    // 最初に戻す
    penMode = 0;
  }
}

これは極端な例ですが…両者は同じ実行結果になるものの、見やすさの差は一目瞭然ですね。コードの整形はProcessingの自動フォーマット機能が便利なので、積極的に使っていきましょう。

コメントを書く

コードを書くのに慣れないうちは、どんどんコメントを書きましょう。

// (mouseDragged って何だっけ…?)

void mouseDragged() {
  
}
// マウスをドラッグしたときに実行されるブロック
void mouseDragged() {
  
}

意味のわかる変数名をつける

数ヶ月後の自分は他人です。時間が経ってからコードを見直したとき、本人すら読めなくなっているという悲劇が世界中で発生しています。

たかだか数文字分をケチって意味がわからなくなってしまうくらいなら、少し長くても構わないので親切な名前をつけておくことをおすすめします。

// (何に使ってる変数だっけ…?)
float s;
// (ボールの大きさに使っている変数っぽいな)
float ballSize;

本章のまとめ

  • エラーメッセージには解決のヒントが含まれていることが多い
  • println() やデバッガを活用すると便利
  • 親切なコードを書くと幸せになれる