3.8 Tips: デバッグ、エラーへの対応

3.8.1 デバッグとは

デバッグ(debug)という行為は、プログラミングを効率的に進めていくために非常に重要です。
このdebugのbugという英語の直訳は”小さな虫”です。つまり、小さな虫=小さな間違いであり、デバッグは「小さな間違いを取り除く」という意味です。
デバッグの方法はそれぞれの言語や開発環境によって若干異なりますが、Processingでは、println()print()という機能が用意されています。

次のサンプルをProcessing上で実行してみてください。

int a;
int b = 10;
int c = 4;

a = b + c;

println(a);

すると、コンソールにaの値、「14」が表示されます。
このように、常に変数の値を監視することによって、プログラムが正常に作動しているかどうかを確認することができます。

なお、print()もprintln()とほぼ同じ機能ですが、println()は値を表示すると同時にコンソール上で改行してくれるので便利です。特に理由がなければprintln()を使いましょう。

3.8.2 デバッガの利用

デバッガ(Debugger)は、バグを見つけたり修正するための支援機能です。
Processingはバージョン3以降、デバッガが標準搭載されています。デバッガがうまく使えるかどうかは、プログラミング上達の鍵になります。

●デバッガの各部名称

2016_09_19_2_32
図3.8-a


A. Debug(デバッグ開始/停止)
B. Step(一行ずつ実行)
C. Continue(次のブレイクポイントまで実行)
D. Stop
E. デバッグモードのON/OFF

●デバッガの使い方

まず、デバッグモードをONにします。すると、Variablesウィンドウが開きます。ここに変数の値が表示されます。

2016_09_08_14_53
図3.8-b

次に、ブレイクポイント(一時停止ポイント)を設定します。ブレイクポイントは一時停止して変数の値を確認したい箇所に設置します。クリックによって、ON/OFFできます。

while_loop___processing_3_1_1
図3.8-c

B.のDebugボタンを押してデバッガを開始します。するとブレイクポイントで一時停止します。
一時停止したポイントでは、その行のコードはまだ実行されません!デバッガがその行を通過して初めてコードが実行されます。

while_loop___processing_3_1_1
図3.8-d

●ContinueとStep

デバッガがブレイクポイントまで来たら、ContinueかStepを選びましょう。
Continueは次のブレイクポイントまでのコードを実行します。他にブレイクポイントがなければ、プログラムは終了します。
一般的にはContinueの方が使用頻度は高いでしょう。まず、怪しいところにブレイクポイントを設置して変数を監視します。
また、Stepは一行ずつコードを実行します。
Continueとブレイクポイントの組み合わせで検索しても分からない場合、Stepを実行してより詳細に検証できます。

●サンプル

ここでは、for文の学習の際に利用したサンプルを使ってデバッグしてみます。

while_loop
図3.8-e
リスト3.8-a
int eSize = 5;  //円の直径を設定する

size(200, 200);
background(255);
noStroke();
fill(200, 0, 50);  //色を設定

//iは0から始まって、200以下の場合は繰り返され、
//繰り返すたびに10が加算されていく
for (int i = 0; i <= 200; i += 10) {    
  ellipse(i, 100, eSize, eSize);    //円を描く
}

10行目のellipse()にブレイクポイントを設置してデバッガを実行してみてください。Variablesウィンドウに宣言した変数の値が表示されます。そこから、ContinueもしくはStepを使って、その後の変数の値がどう変化するかを観察してみましょう。
コードが複雑になればなるほど、変数の値の変化は分かりにくくになります。そのような場合にはデバッガを積極的に利用して、効率のいいバグ検出を心がけてください。

3.8.3 エラーへの対応

初心者にとって大きなハードルのひとつは「エラーが出るが、なかなか原因がよく分からない」という問題でしょう。実際、プログラムが複雑になればなるほど、エラーの原因を見つけることが難しくなり、デバッガを活用しても分からないことがあります。
これは、初心者に限らず上級者にとっても悩ましい問題です。逆に、プログラミングができる人は「エラーを見つけるのがうまい」ともいえます。
この問題を解決するには経験を積むしかないのですが、エラーメッセージを読解することによってある程度は解決する場合があります(しない場合もありますが)。

Processingはver.3以降、かなりエラーメッセージが分かりやすくなっています。
例として、次のサンプルを実行してみましょう。

リスト3.8-b
int a = 0
int b = 10;

size(400, 400);
background(255);

for (int i = 0; i < width; i += 10) {
  ellipse(i, height/2, 10, 10);

この場合は、2箇所エラーがあります。Processingの最下部にある「Errors」タブを選択して確認してみると、エラーの可能性がある箇所が複数表示されます。そして、右端には行番号も表示されるので、表示された行の周辺を探しましょう。
注意:問題の箇所は表示行から数行ずれる場合もあります。

2016_09_19_3_15
図3.8-f

ここでは、次の2点に問題がありました。
英語のエラーメッセージなので、英語が苦手な人はそれだけでメッセージを読む気がなくなってしまいそうですが、大体のエラー箇所が分かれば英語のメッセージを熟読しなくても大丈夫です。

●メッセージ
Missing a semicolon “;”

●エラーの理由
行末のセミコロンが抜けている

//例
int a = 0
int b = 10;

●メッセージ
Missing right curly bracket “}”

●エラーの理由
for文を } で閉じていない

//例
for(int i = 0; i < width; i += 10){
  ellipse(i, height/2, 10, 10);