kr_ryo 徒然日誌 <2003年11月9日分>

三國志製作記38〜バグ退治!〜

先週バグ取り記にはなりたくな〜い(T-T)って言ってましたが、バグ取り記です(ToT)いやあ、はまると大変です(T-T)とにかくそこが直らないと全然前に進みませんもの。別の所で先に進んでも、いずれそこは直さないといけないですしねえ〜(;_;)

Delphiは以前から何度か書いていますように、オブジェクト指向言語です。オブジェクト指向言語でのプログラムは、ひたすら手順を追って延々描くのではなく、処理対象を細々とした部品と扱い、その組み合わせで処理を表現します。けれども、これまでも何度か書いていますが、相変わらずわかった気になりません(^^;「オブジェクト指向」についての本も何冊か立ち読みしたんですが、やっぱり、そっか!という気になりませんでした(;_;)何度かわかった!と書いていますが、しばらくするとやっぱりなんだかわからなくなることが多いです(--;

このオブジェクト指向言語だと、バグ取りが簡単になると言われています。ところが現にバグ取りの最中には、そうとは全然思えない(^^;ちょっと前までは、ひたすら処理を延々描いているとどこが間違っているかわからないけれど、部品ごとに細切れにすると、エラーの出た部品が明らかになりやすいからかしら?と思っていました。しかしどうもそれだけではないような?

実は今、オブジェクト「指向」だったか「志向」だったかわからなくて、我が愛用IMEのJapanistの辞書を見ましたところ、「処理手順やデータ構造中心の手法と異なり、処理対象(オブジェクト)そのものを中心に展開する情報処理の考え方」とありました。これでまた何かが腑に落ちました(^-^)

今までオブジェクトとしてのプロシージャ(手続)、つまり部品を、どういう単位で作るのか今ひとつわかったような、わからなかったような、でした(^^;長いなが〜い部品・関数にしてはいけない、と色んな本に書かれていましたが、それよりむしろ、機能部品ごと、なんですよね(^-^)長くてもプロシージャは、ひとつの機能を持った部品で、処理すべき対象の入出力があるべき、ということです。もちろんひとつの機能の処理が長ければ色んな要素があるはずなので、部品内部品として別にすべきです。としても、長いことは避けるべき、ではありますが、長いから分ける、というのではなく、機能=処理対象を中心に見るんですねえ〜(@_@)

どうもこれまでプロシージャを起こすのは、あ、長くなったから分けよっかな?っていう感じでしかなかったんですが(^^;定義から思うに、こういう処理を行いたい、というように、処理(対象)を中心として、こういう処理を行うにはこれがああなってここからこうしてああして、で、こうする、という感じでひとまとめにして起こすべきですね〜(^o^)いやあ、長い本を読まなくても、ああ、そっか、とわかる感じというのはあるんですね(^^;;;まあ、今までよく分かってなかったということで(^^;A

ある処理を行うためのプロシージャですから、実行してみて、ある処理がきちんとできていなければ、その処理の部分の手続=プロシージャを見ればいいのです(^-^)なるほど、だからオブジェクト指向言語はバグ取りが容易になるのか〜(@_@)

これとは異なり、手順指向だと、命令が処理すべき順番に並んでいるだけだから、ある処理が思い通りにいかなかった場合、その処理がなされている部分を抽出して分析しないといけない。ところが思い通りにいかなかった処理の部分には何も間違いがない!(*_*)プログラム全部を分析してはじめて、実は別の処理と思い通りいかなかった処理とが混同されていて、データなどが誤って思い通りにいかなかった処理に取り込まれていた、ということがわかったりします(~_~;)

もちろん、どうもこの理解は構造化プログラミングでも実現できる内容で、オブジェクト指向の3原則など高度にオブジェクト指向的ではありませんが(^^;土台としての理解としては間違ってないでしょう。処理内容中心、ねぇ〜(@_@)単に短くするんじゃなくて、処理内容をメインに分けていくんだ〜(^-^)

という感じで感心しつつ、バグ取りです(^^;前回以来のバグとは、リストの並べ替えボタンを押すと、いったん内容を消して次の別の内容を表示させた際、「リストのインデックスが範囲を超えています」というエラーが出て止まってしまうということです(*_*)

実はなんとか直したので今ではこのエラーの意味がよくわかりますが、当初はいったいなんのことか全くわからず、色んな部分をいじっていました(--;リスト内容として、ソートのため表示させない要素も持たせるという細工をしていたので、その部分が間違っているのかな?とか、以前バグ取りにはまったというお話をした時の、同じ処理が繰り返されるという問題の派生かな、とか…

ひたすら処理の流れを追っていっても、どちらにも問題はありません。結局答えは、ソートする項目番号を表す変数の数値が初期化されていなかったため、最初のリスト内容を消して、次のリスト内容を表示させようとした際、最初に並べ替えを実行する設定だったため、まだ全部の内容を入れる前にソートする手続が呼び出され、ここで変数の数値が残ったままだったので、予定しない並べ替えが実行される、すなわちまだ入れられる前の、入っていない内容をソートすることになってしまった、というのがエラーの中身でした(*_*)

リストのソートのプログラムは、ヘルプの例を参考にして書いたため、相変わらずお仕着せで微妙に分かっていない内容のため、発見が遅れました(^^;オブジェクト指向だから気づきにくかった面もありますが、厳密にオブジェクト指向だと起こらなかったとも言えます(--;)

どういうことかというと、まず、ソートのために、どの項目でソートするのか、ユーザがクリックした部分を記録するための変数が必要になります。オブジェクト指向のため、変数もある処理を行うプロシージャの中でしか存在せず、プロシージャが終わると変数は初期化されます。そのため変数の内容を複数のプロシージャやオブジェクトにまたがせる場合、その樣に宣言したり、次のプロシージャにデータを渡してやらないといけません。問題の先の変数は複数のプロシージャで使うものですよ、という宣言をされていました。

そして、リストの枠は同じで、表示させる内容をいったん消して、別の内容に変えようとした際、変数の内容が初期化されていなかったため、先程説明した問題が起きることになります。要するに、普段変数は次の処理に送らない限り消えている、という状態に慣れていたため、お仕着せの、データをプログラマーが消さないと消えない変数の宣言をされていた部分に気づかなかったということです(^^;

もちろんその変数や処理を、きちんとオブジェクトにしてまとめてしまっていれば問題は起こりにくかったかもしれません。まあ、そこまでおおげさなものでもなかったもんですから(^^;

な〜るほど、と次のリストを表示する前に変数を初期化してバグ取り完了!(^o^)なんとか動くようになりました(^^;文章にすると短いですが、この間2週間程度?(*_*)はまるときついですねえ〜!今回この割と久しぶりな硬めの(わかりにくい?(T-T))プログラムの話題なのも、ひたすら原因追及のために時間を取られ、結局動いたものの全体としてはほとんど進んでいないためです(~_~;)延々1行づつ止めてデータ内容を確認したり、行き先を確認したりしてようやくわかりました、が、労力の割に何かを生産したわけではないので(T-T)中身は進んでいないのです。ううむ、システム会社にプログラムを頼むと高いのもわかる気がする…(--;)実際のプログラム製作もさることながら、こういう地道なエラーチェック、バグ取りに時間を取られているんでしょうねえ〜(^^;

しかし、まあ、エラーを直していく過程で、よくわからなかったDelphiのオブジェクトとしてのリストなどの機能もわかってきたし、悪いことばっかりではないですね(^-^)気を取り直して、またがんばってみま〜す!(^o^)けどその前に、結構疲れたから、ちょっとコサックスでも…(^^;;;

index

〔TopPage〕

このページへのリンクはフリーです。
このページについてのご意見、ご質問などは、kr_ryo_green@yahoo.co.jpまでお願いします。
Copyright 2003© kr_ryo All rights reserved.
訪問件数