デバッグ

コンピュータに与えるプログラムに含まれる論理的誤りのことを バグ という。

プログラムにひそんだバグを取り除く作業のことをデバッグ とい う。デバッグするためには、プログラムが動くときのことを頭の中で追いかける 必要があるので、文法エラーを取り除くのよりはるかに時間がかかる。プログラ ムを作る過程では、最初に書き進めて行く時間よりも後から間違いを直す(デバッ グする)時間の方が長い。熟練するにつれ、デバッグにかかる時間が短くなり、 同時に最初からバグの少ないプログラムが作れるようになる。

学習が進むにつれ作成するプログラムも徐々に複雑になっていくので、 プログラミングに掛ける時間を節約する意味で、

を覚えておこう。

エラーを起こしにくい書き方

開けたらすぐ閉める!

if, while, open などは必ず対応する end を書く必要がある。にもかかわらずend を忘れてエラーになることが最初のうちは多い。end を後 で入れるから忘れるのである。endで閉じるべき 構文を書いたら、すぐに前もってend を書くようにすると忘れない。

if y%7 == 3 then
    ←endを書いてから中味を書き始める
end

括弧や引用符 ( ) [ ] "" '' も同様で 閉じ忘れると大量のエラーメッセージに見舞われる。開けたらすぐ閉じて 戻って中を書くようにすると絶対に閉じ忘れがない。

printf("")    まず閉じ引用符、閉じ括弧を打ってから
  ↓
printf("答は...")  戻って中味を入力
変数名は分かりやすく

大事な意味を持つ変数を、xとかx2 無味乾燥な名前にせず、maxninzu, goukei といった 値の意味が想像しやすい名前にする。

また、変数名の綴り間違いでエラーになるのは悲しいので、 積極的に補完を利用する。Emacsであれば単語を2〜3文字打った状態で M-/ を押すとバッファ内に同じ単語があったときに 単語の残り部分を補ってくれる。

大事なところにコメントを付ける

制御構造や条件分岐にはかならず意味があるはずである。 意味を表すようなコメントを書いておく。

無意味なコメントの例

point=[]			# point配列を用意
sum=0				# sumを0にする
i=0				# iを0にする
while line=gets			# getsの間繰り返す
  point[i] = line.to_i		# point[i]にline.to_iを代入
  sum += point[i]		# sumにpoint[i]を足す
  i += 1			# iに1を足す
end

意味のあるコメントの例

point=[]			# 全員分の得点を記憶する配列
sum=0				# 合計を保存する変数をクリア
i=0				# 今何人目か
while line=gets			# 入力が続く間繰り返す
  point[i] = line.to_i		# i人目の得点を記憶
  sum += point[i]		# 合計得点に追加
  i += 1
end

Emacsであれば、M-;(メタセミコロン)をタイプすると簡単に 決まった桁位置に # が入れられる。

デバッグのしかた

printfデバッグ

プログラミングの初歩の段階では、変数の値が未定義だったり、 変数の値を変えずにループを作って暴走させてしまったりと、 変数の値が予期せぬ状態になっていることが原因のバグが多い。 これを確認するために、現在の変数の値を要所要所で出力する printf を差し込むとよい。

line=gets
while match > 0
  printf("debug: 今のマッチは%d本\n", match);
   :
   :
end

このように、printf を挟んで、そのときの変数状態を 表示してデバッグする方法を、printfデバッグ といい、初歩的ではあるが複雑なプログラミングのときにも 有効な方法である。

pメソッドの利用

Ruby特有の便利なメソッドとして、p がある。pは1つ以上の引数を受け取り、文字列は文字列と分かるように、 配列は全ての要素を列挙して配列と分かるように、その他の構造の値も 目で見て分かりやすい形で出力してくれる。

p.rb

#!/usr/koeki/bin/ruby

number = 5
string = "えっほえっほ"
a = [100, "foo", "ばあ"]

p number, string, a

$KCODE = 'e'
p number, string, a

上記のプログラムを実行すると以下のようになる。

% ./p.rb
5
"\244\250\244\303\244\333\244\250\244\303\244\333"
[100, "foo", "\244\320\244\242"]
5
"えっほえっほ"
[100, "foo", "ばあ"]

値に日本語文字列を含む場合は、Rubyの組み込み変数 $KCODE"e" を代入してから pメソッドを呼ぶ必要がある。e はEUCを意味する。

配列の値がどうなっているか確かめるときにはpメソッド が有用である。


本日の目次