この記事では Small Basic 言語で書かれたプログラムの以下のようなデバッグ手段を紹介します。また、発行されたプログラムについてデバッグの実例を示します。
もしあなたのプログラムにおかしなところを見つけたとき、どのようにして探しますか。Small Basic IDE (統合開発環境)には変数をウォッチ(監視)するような機能はありません。しかし、変数に期待しない値が入ってしまうことがよく起こります。 それを見つけるには TextWindow.Write() または TextWindow.WriteLine() をデバッグのために追加し、変数の内容を見てみるとよいでしょう。
配列 arry の内容を見るには、単純に TextWindow.WriteLine(arry) を使用するか、以下のようなコードを書きます。
TextWindow.ForegroundColor =
"Yellow"
num = Array.GetItemCount(arry)
index = Array.GetAllIndices(arry)
For
i =
1
To
num
TextWindow.WriteLine(
"arry["
+ index[i] +
"]="
+ arry[index[i]])
EndFor
"Gray"
テキストベースのプログラムのデバッグの場合、前景色 (foreground color) を変更することにより、プログラムの本来の出力とデバッグのためのメッセージを区別しやすくできます。
配列の内容を表示するようなデバッグのためのサブルーチンを書いた場合、それは将来も役に立つ可能性があります。しかし、これらのコードが必要なのはデバッグ中だけです。そこで、debug フラグを使ってデバッグルーチンをオン・オフします。
Maze 0.4 (PNC833-0) は debug フラグを使ったひとつのサンプルです。以下の行で debug フラグをオフにしています。debug = "True" によってフラグをオンにします。
27.
debug =
"False"
以下の 4 行は配列 "cell" に作られた迷路をテキストとして表示します。
61.
If
debug
Then
62.
DumpMaze()
63.
TextWindow.WriteLine(title)
64.
EndIf
以下のコードは迷路の生成をゆっくりさせて見えるようにし、変数を表示したあと、TextWindow.Read() を使ってポーズ(一時停止)しています。
229.
230.
Program.Delay(
20
)
231.
232.
' 2. Add the neighboring walls of the cell to the wall list.
234.
AddWallToList()
235.
236.
"iWalls="
+ iWalls)
237.
TextWindow.Write(
"nWalls="
+ nWalls)
238.
TextWindow.Read()
239.
そしてデバッグが終わったら、これらの行は(Small Basic IDE の [Ctrl]+F で)簡単に見つけ削除することができます。実際にこれらのルーチンは Maze 1.2 (PNC833-12) では削除されています。
汎用的な(応用範囲の広い)サブルーチンを書くことは生産性の向上に貢献します。筆者の場合、色、計算、マウスなどのサブルーチンを多くのプログラムで再利用しています。ただし汎用サブルーチンにはバグがないよう、よくテストしなければなりません。バグが無いこと(少ないこと)が生産性の前提条件ですから。
サブルーチンをテストするためには、サブルーチンのためのテストプログラムを書くのが合理的です。よいテストプログラムはバグを見つけるだけでなく、デバッグ後のリグレッション(品質低下)のチェックをも簡単にしてくれます。
大きな数 n の組み合わせ nCr を求めるプログラム (CPQ608) には、TestDiv() というルーチンがあり、汎用的なサブルーチン Div() をテストします。
以下は TestDiv() で見つけた Div() に問題を起こすパラメタです。
'a = "434399216531770650390143258708"
'b = "6752306690329"
'a = "397896921587794748049229269710"
'b = "8642083658481"
以下のリストは Shapes 1.1 (TLW744) のデバッグ中に書いたものです。たくさんのコードを一度に書くと、プログラムがたくさんのおかしな振る舞いを起こすことがあります。こういうときは、それらの現象をひとつひとつ書き留めてリストを作るとよいでしょう。なぜならそれらの現象にはたくさんの原因があることが多いからです。さらにデバッグ後には、このリストがプログラムのためのよいテストセットになります。
Small Basic で表示されるエラーメッセージには 2 種類あります。ひとつはコンパイルエラーです。もうひとつはランタイムエラーです。これらのメッセージの意味を知ると開発の助けになります。
コンパイルエラーは [実行] ボタンを押した後、プログラムに文法的なエラー(誤り)があると、ソースコードの下に表示されます。以下の図はプログラム Fifty (BRQ733) のコンパイルエラーを示しています。
いくつかのエラーが発見されました... 11,28: 変数 'files' は使われていますが、それに対する値は指定されていません。正しく値を指定したか確認してください。 29,24: 変数 'buf' は使われていますが、それに対する値は指定されていません。正しく値を指定したか確認してください。
先頭の数字はソースコードの問題の個所の行と桁を表していて、エラーメッセージをダブルクリックすることで、その場所へジャンプすることができます。これらのコンパイルエラーメッセージには、何が起きたかということと、それを修正するためのアドバイスが書かれています。上記のケースでは、File.GetFiles(path) と File.ReadContents(filename) のある行がSmall Basic サーバによって自動的にコメント化されているために、エラーになっています。コメントを元に戻して実行し直すとエラーはなくなります。
一方、ランタイムエラーはプログラム実行時に、実行を続けられない問題が発生したときに表示されます。以下の図はゼロ除算が起きたときの事例です。
Decimal 型の値が大きすぎるか、または小さすぎます。 場所 System.Decimal..ctor(Double value) 場所 Microsoft.SmallBasic.Library.Math.Remainder(Primitive dividend, Primitive divisor) 場所 _SmallBasicProgram._Main()
このテキストボックスに表示されたリストは「スタックトレース」と呼ばれるものです。このリストはエラーの時点でどのサブルーチンがどのサブルーチンを呼んでいるかを表しています。上記のケースでは、スタックトレースはプログラムのメインの部分から余りを求める Math.Remainder() が呼ばれてエラーが起きていることを示しています。実際、divisor (割る数)に 0 が与えられていたためにこのエラーが起きました。
たくさんのデバッグルーチンを書いたにもかかわらず、バグによっては複雑すぎて原因を見つけられないことがあります。最後の手段としては、「昇格する」ボタンを押して Small Basic プログラムを Visual Basic プログラムに変換してしまう方法があります。このことによって Visual Studio の強力なデバッガを使用して元の Small Basic プログラムにあったバグを探すことができます。
ステップ 1: まだ行っていない場合は、Visual Basic 2010 Express をインストールします。 ステップ 2: 「昇格する」ボタンを押し、Visual Basic プログラムに変換するためのフォルダ名を入力します。 ステップ 3: Visual Studio 変換ウィザードで [次へ] または [完了] ボタンを押します。プログラム XXX.sb (または XXX.smallbasic)は XXXModule.vb に変換されます。 ステップ 4: スコープエラーを回避するために、'For i = 1 To n' を 'For XXXModule.i = 1 To n' に書き換えます。 ステップ 5: 必要に応じてソース行をダブルクリックし、ブレークポイントを設定します。 ステップ 6: [デバッグ開始] ボタンまたは [F5] キーを押し、プログラムを起動します。 ステップ 7: もしプログラムがブレークポイントで停止したら、[ステップ イン (F8)] または [ステップ オーバー (Shift+F8)] を押して次へ進めます。 ステップ 8: 「自動変数」、「ローカル」または「ウォッチ」タブを見て、変数の値を確認します。 ステップ 9: もしバグを見つけたら [デバッグの停止] ボタンを押し、プログラムを修正しコメントを残します。 ステップ 10: ステップ 6 以降を繰り返します。
そして、バグの改修を確認できたら、Small Basic IDE に戻って Visual Studio で行った修正を行います。
Small Basic と Visual Basic では以下のような文法の違いがありますので、適宜書き換えを行ってください。
これらの方法は、ここ 2 年の Small Basic プログラミングの成果ですが、全てというわけでありません。プログラミングやデバッグには創造性が大切です。もしもあなたがよい方法を発見したら、是非その方法をこの記事に追加してください。Small Basic はとてもコンパクトでプログラミングを学ぶのにとても適した言語です。しかも簡単で強力です。
Nonki Takahashi edited Revision 23. Comment: changed the way to avoid scope error / スコープエラーの対処方法を変更
Nonki Takahashi edited Revision 22. Comment: Visual Basic での For 制御変数に関する情報を追記
Nonki Takahashi edited Revision 21. Comment: Visual Basic での配列の扱いを訂正しました。
感謝 :)
「昇格する」 is displayed as 「昇格する」. I reported this issue in social.technet.microsoft.com/.../da9582fe-6efd-40ea-9329-3a36d6bdd5ec .
「昇格する」が「昇格する」と表示されています。この件については上記URLに報告済みです。
�� has been appeared, but original text is not broken... What happened?