今日もせっせこツールの開発。本来は2ヶ月後くらいにやる予定だった内容を訳あって前出ししてます。
業務で使用しているチューニングツールなんですが、VB6で書かれてるんですな。そのツールの改造及び新機能追加のノウハウを習得ってことでカリカリ書いてます。
改造と新機能追加のノウハウについてはおおよそ把握できたんですが、今日2つほど罠にはまっちゃいまして。
まず1つめは、VB6(というかVisualStudio6.0?)の仕様による罠。
IDEからデバッグモードで実行し、その実行中のプロセスが何らかの原因で暴走した場合(大抵の場合、WinAPIに絡んでの暴走)、IDEを巻き込んで落ちてしまいます。というか、暴走したプロセスを落とすのにIDEから落とす必要があります。
で、更に性質の悪いことに、ビルドしてexeを生成するか、明示的に保存しない限り、プロジェクトに対する変更は保存されていません。デバッグ実行毎に保存されているのかと思いきやそんなことはありません。
そのため、結構ノリノリでソースを書いてデバッグ実行で暴走したら、とても悲しいことになります。
…ってかなりましたOrz 2時間分くらいが吹っ飛んだかな…。
まぁ、その2時間の内訳は、8割方が実装方法の思案に費やされてましたので、復旧作業自体は20分程度で終わりました。気分としては悲しかったがな!
2つめは、設計上の罠。
とあるUIでは、設定したパラメータを保存はしているけれど読み出しがまだ実装できてなかったので、その読み出し機能を追加することとなりました。
パラメータを読み出して、各パラメータのテキストボックスに放り込むところまでできました。
で、それは割合あっさりとできたんですが(途中上の罠に引っ掛かって時間を浪費しましたがw)、それをさらにファイルへ保存しようとしたら、あらまびっくりパラメータの部分が空白。
っかしいなぁと思ってパラメータ保存のルーチンを確認すると、どうもテキストボックスの値を保存しているわけではない模様。テキストボックスの値を別の変数に入れてるんですが、そちらの値を参照しているらしい。
つーことで、いつその変数にテキストボックスの値を代入しているのか調べたら、なんとテキストボックスのLostFocusイベントでやってやがる。
VB6のテキストボックスにはバリデーションチェック機能は基本的についておらず、「数字だけしか入力しちゃダメ!」みたいなのは自前で実装しなきゃいけないんですよね。
まぁそれ以外にも、入力範囲が決まっている場合なんかも、入力された値がその中に収まっているかをチェックする必要があります。
で、それをどのタイミングで実行するかってのが実装者に委ねられるわけですが、ここを設計した人はどうもLostFocusイベントで実装していたようで。
ここは好みが分かれるところかも知れませんね。私はLostFocusのタイミングでは判断しないでほしい。なにか他の処理を実行するボタンを押したときのように、その値が確定した段階でチェックをする派です。
まぁ、「入力した時点で間違いは分かるだろ? だったらその場で教えてくれよ」って人もいるでしょうし、それは要求仕様次第、それが特になければ実装者次第なのは納得できます。
んが、どうもこれを設計した人はパラメータロードについては一切考慮してくれなかったようで(パラメータセーブは作ってるのになぁ…)、バリデーションチェックのコードはイベントハンドラの中にベタ書き。サブルーチンにはしてくれてませんでした…。
まぁその部分だけサブルーチンにしてもよかったんですが、面倒だったのでパラメータを呼び出してテキストボックスに放り込んだ後、テキストボックスのLostFocusイベントハンドラを直接叩くという暴挙に(絶対にマネしないでね!)。
するとどうでしょう! 片っ端からバリデーションエラーにwww
ただ、それもおかしな話なんですよ。そのテキストボックスには数字で「0〜1.0」が入るようになっており、それ以外の数値なり文字が入ったら「異常な入力値です!」というダイアログとともに、テキストボックスが赤に変化するというイベントハンドラの内容でした。
が、保存したパラメータファイルから読み出した値は「0.6」とか「0.3」など、バリデーションチェックが通るものばかり。
どないなっとるねんとか思いながら、手動でパラメータを打ち込んでみても結果は同じ。
なんじゃそらってことで、追加した暴挙の部分、イベントハンドラを直接読んでいる部分をコメントアウトして再挑戦。
…してもやっぱりバリデーションエラーが…Orz
おかしい。そもそもLostFocusのイベントに絡む部分を書き換えた覚えは一切ない。勝手に呼び出すコードは追加したけれど、別に呼び出しに問題はないだろう(是非はともかく)。大体、その追加した部分をコメントアウトしても発生してるんだからそもそもそこじゃない。
で、一体いつからこの現象が発生しているのかを調べるため、機能改造前のexeで確認したところ、件の現象は発生しませんでした。
ということは、私がコードを追加したことで何らかのバグが混入したか、あるいはもともとバグが潜んでいたけれど運良く(悪く?)発現してなかったものが発現したかどちらかでしょう。
とりあえず、もう定時だったのでこれ以上の追求は明日に回すことにしましたが、非常に気持ち悪い。そもこのプロジェクトがやたらめったらグローバル変数を使っていてなおかつパスタなコーディングをしているがために、どのタイミングでどの変数にどんな値が入っているかがイミフなんですよねぇ…。
明日詳しく解析はしていきますが、ほんっと早いとこ.Net版が使い物になるところまで持っていこう。これ以上こんなカオスなコードは増長させちゃいかんわ…。
0 件のコメント:
コメントを投稿