PR

 「プログラムが完成したはずのに,コンパイラすら通らない」「きちんと動いているように見えるが,思った通りの結果が得られない」---。プログラミングの経験者ならだれもが,自分が作成したプログラムの不具合(バグ)に悩まされたことがあるだろう。

 特に日常的にプログラミングをしていた学生時代は,筆者もしょっちゅうバグに悩まされた。バグがなかなか直らなくてイライラするあまり,文字通り,パソコンを投げてしまったことさえあったほどだ。

 そんなことを思い出したのは,ここしばらく,バグを生みにくいプログラムの作り方やバグの取り方について考えていたからだ。ヒントを得るために,知り合いのソフトウエア開発者たちにバグの解消法を聞いて回ったところ,様々な答えをいただいた。「トライ&エラーの繰り返し」「デバッガを利用する」「ログを出力する」などだ。

 いただいたアドバイスをみると,「バグ取りに近道はない」と同時に「遠回りしないことも大切」ということを強く感じる。当たり前に思えるかもしれないが,具体例とともにこれらを説明しようとするとなかなか大変だ。ケアレスミスがないかをしっかり確認したうえで,一つひとつ着実に内容を確認していく。そのための手段として,あるソフトウエア開発者は,「どんなに熟練のプログラマでも,デバッグの際には1文字15秒ぐらいかけてじっくり確認していくものだ」と教えてくれた。

 筆者はついこの間,自分で書いたコードで,落ち着いてしっかり確認していくことの大切さを実感した。そのコードは,プログラミング言語Rubyで記述したものだった。バグを含んだ部分を抜粋したものがリスト1である。

リスト1●Rubyで記述した,バグのあるコード。著者は1文字ずつきちんと確認しなかったばかりに,バグ取りに30分もかかってしまった
array1 = (1..100).to_a
array2 = array1.select(|i| i%7 == 0)

puts array2

 見ての通り,とても簡単なプログラムだ。配列に1から100までの整数を格納して,7の倍数だけを抜き出すというものである。おそらくプログラミングにたけた人ならば,ほんの3秒で解決してしまうバグかもしれない。

 ところが著者は,プログラムの短さに油断したせいもあってか,あてずっぽうにコードを修正するばかりで,“正解”になかなかたどり着けなかった。恥ずかしながら告白すると,30分ほど試行錯誤したあげくにようやくバグの原因を突き止めた。

 リスト1をよく見ると,selectメソッドの後ろの「{ }(波カッコ)」が「( )(丸カッコ)」になっている。先のアドバイスのように,1文字ずつしっかり確認していけば,ものの3分もかからずに解決できる問題だったと思う。バグ取りの近道をいいかげんな推量で探すあまり,結局は遠回りしていたのである。

 このことを取材先のプログラマに話したところ,その場にいた5人ほどのプログラマの意見は一致していた。プログラムが動かない,その理由は,

そんなプログラムを書いたおまえが悪い!

 確かにその通り。プログラムのバグへの対処は,近道があるわけでもなく他人任せにもできない。自分が悪い以上,自分できちんと解決しなければならない。しかもなるべく遠回りせずに。

 遠回りせずにソフトウエアの不具合を解消するためのソフトウエア開発者たちの知恵を,日経ソフトウエア2009年1月号の特集1「必ず動くプログラムの作り方」にまとめた。ここでは,プログラミング言語のJavaと統合開発環境のEclipseを使ったデバッグ方法や動くコードを書く10のヒントなどを取り上げて,なるべく具体的にバグの少ないプログラムの書き方を解説している。

 最後に10のヒントの一例を挙げよう。よくバグを埋め込みがちな,オブジェクトの比較だ。以下に示すリスト2では,同じ文字列を比較している。簡単な例なのでJavaを少しでもかじったことのある方ならおわかりだろうが,,printlnメソッドで引数を出力している。引数の文字列が同じものならtrueを,違うものならfalseを出力する。

リスト2●Javaでオブジェクトを比較した例。(1)と(2)が出力する値がすぐにわかるだろうか
class ListTest {
  public static void main(String[] args) {
    String s = new String("Nikkei Software");
    String t = new String("Nikkei Software");
    System.out.println(s == t);       //(1)
    System.out.println(s.equals(t));  //(2)
  }
}

 (1)と(2)の出力結果がすぐにわかるだろうか。(1)がfalse,(2)がtrueになる。うっかりしているとこのように単純な文字列の比較でも,バグを埋め込んでしまう可能性がある。著者も学生時代からこうした具体的な解消法を知っていれば,パソコンを投げずに済んだかもしれない。