コンピュータに与えるプログラムに含まれる論理的誤りのことを バグ という。
プログラムにひそんだバグを取り除く作業のことをデバッグ とい う。デバッグするためには、プログラムが動くときのことを頭の中で追いかける 必要があるので、文法エラーを取り除くのよりはるかに時間がかかる。プログラ ムを作る過程では、最初に書き進めて行く時間よりも後から間違いを直す(デバッ グする)時間の方が長い。熟練するにつれ、デバッグにかかる時間が短くなり、 同時に最初からバグの少ないプログラムが作れるようになる。
学習が進むにつれ作成するプログラムも徐々に複雑になっていくので、 プログラミングに掛ける時間を節約する意味で、
を覚えておこう。
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つ以上の引数を受け取り、文字列は文字列と分かるように、
配列は全ての要素を列挙して配列と分かるように、その他の構造の値も
目で見て分かりやすい形で出力してくれる。
#!/usr/koeki/bin/ruby # -*- coding: utf-8 -*- number = 5 string = "えっほえっほ" a = [100, "foo", "ばあ"] p number, string, a
上記のプログラムを実行すると以下のようになる。
./p.rb
5
"えっほえっほ"
[100, "foo", "ばあ"]
配列の値がどうなっているか確かめるときにはp
メソッド
が有用である。
プログラムの動きを止めながら、1行ずつ実行しては変数の 値を確認することができる。このような道具を ソースレベルデバッガ といい,EmacsでRubyプログラムを作成 する場合には rubydb が使える。
コマンドラインからプログラムを起動するときに、
rdbg
によって行う。たとえば以下のようにする。
rdbg program.rb
と入力する。すると,デバッグモードでプログラムが起動する。
この画面のデバッガプロンプト「(rdbg)
」
で入力できるコマンドの代表的なものには以下のものがある。
s
(step)
ステップ実行。1行ずつ実行する。
n
(next)
次の行まで実行。メソッド呼出しはトレースされない。
c
(continue)
継続実行。ブレークポイントで止まる。
b
(break)
「b
行番号」などとして、
ブレークポイントを設定する。引数を省略すると設定されている
ブレークポイント一覧を出す。
d
(delete)
「b
行番号」などとして、
指定したブレークポイントを除去する。引数を指定すると
全て除去する。
p
(print)
「p 変数
」などとして,p
の後ろに書いた変数の値を表示する。
l
(list)
ソースプログラムを表示する。
disp
(display)
「disp 変数
」などとして,
変数の値をステップ実行ごとに常時表示する。
undisp
により解除できる。
短いプログラムの場合はデバッグバッファで,s を打ち続けて1行ずつ実行を進めて,適宜変数の値をpで 表示して確認する。Return を空打ちすると 直前と同じコマンド が繰り返し実行される。
長いプログラム,あるいはループで何度も繰り返すプログラムの場合は 動きを調べたい場所の直前にブレークポイントを設定してから c で継続実行する。ブレークポイントを設定するにはソースプログラムの 該当行番号を調べ、
b 行番号
と入力する。