Perl の 小箱
2007/12/ 2
久しぶりに触ったので、以前理解していたところも再発見のような新鮮さだったが、その一番は、プログラムの本体が Webサーバーにあってその上で動作・データ処理が行われるのに、ユーザ(クライアント=プログラマー)から見ると、あたかも自分のPCの中でそのプログラムが動いているように見えてしまうこと。一般のCなどで作るクライアントマシン用の PCアプリは、一回プログラムが起動したら、少なくともグローバルな変数は終了時まで保持されることとの違いが、コーディング途中での理解の妨げになっていると思う。初歩の初歩のせいかも知れないが、意外とこうした説明にお目にかかったことがない。
これは実際には、下の図のような流れとなっている。つまり実際のプログラムの処理は Webサーバー上で行われ、クライアントのPCには結果の文字列だけが返されて表示されているということだろう。(HTMLファイル中に記述されたJava Script との違いもここにある。Java Scriptはプログラムコードに相当するスクリプトがダウンロードされてから、Browserの中で解釈・実行される。)
従って、上の図の 黄色い部分のように、途中で他のユーザのリクエストによる起動が行われる可能性もあり、「送信ボタン」を一回押す毎に全く新しい処理が発生している。そのことの当然の結果として、各処理の間には全くの関連性はなく、変数などはその度にリセットされる。次回の実行時に必要な変数値は、<input type="hidden" name="catg" value=$...>のような形で非表示属性の埋め込みタグとして一回 クライアント側に戻して、Submitボタンを押したとき再び送信してもらい、それを処理するというような面倒くさいことが必要になる。私は今でも時々 あれ、この変数あそこでセットしたはずなのにどうしてこんな動作になっちゃうんだろう? と思って追っかけると、実は、その回の Submitボタンを押したときには、その代入文の所を通っていないということがよくある。
これは実際には、下の図のような流れとなっている。つまり実際のプログラムの処理は Webサーバー上で行われ、クライアントのPCには結果の文字列だけが返されて表示されているということだろう。(HTMLファイル中に記述されたJava Script との違いもここにある。Java Scriptはプログラムコードに相当するスクリプトがダウンロードされてから、Browserの中で解釈・実行される。)
従って、上の図の 黄色い部分のように、途中で他のユーザのリクエストによる起動が行われる可能性もあり、「送信ボタン」を一回押す毎に全く新しい処理が発生している。そのことの当然の結果として、各処理の間には全くの関連性はなく、変数などはその度にリセットされる。次回の実行時に必要な変数値は、<input type="hidden" name="catg" value=$...>のような形で非表示属性の埋め込みタグとして一回 クライアント側に戻して、Submitボタンを押したとき再び送信してもらい、それを処理するというような面倒くさいことが必要になる。私は今でも時々 あれ、この変数あそこでセットしたはずなのにどうしてこんな動作になっちゃうんだろう? と思って追っかけると、実は、その回の Submitボタンを押したときには、その代入文の所を通っていないということがよくある。
後日追記:その後 Webをうろついていてこんなページを見つけた。コマンドプロンプトから CUIでデバックを実行する方法。自身の勉強不足を恥じるが 一応私の足跡なので以下の自己流も残すことに。
最近の高級言語は、開発環境が整っており、コードを書いてデバッグする際に実行をトレースしたり、変数値をウォッチしたり出来ることが普通になっている。それに比べると フリーウェアで構築できる Perlの開発環境は(私が知る限り)、一切そうした事が出来ない。殆どの場合、サーバーエラーが返されるか、コマンドプロンプトから perl -cw (スクリプトパス) と打ち込んで、問題のある行を表示させることが精一杯。文法エラーがなくて動作はするが、表示がおかしいと言うような場合、コード見ながら変数値やサブルーチンを追いかけるのは非常に大変。
そんな時、私は以下のようにやっている。
メインルーチンで、まず グローバルな文字列変数を定義する。そしてプログラムの要所要所(サブルーチンの頭とか、if文の中)で、その変数に サブルーチンの名前や 変数値を結合していき、HTML出力の最後の方で その文字列変数を プリントする。
実際には以下のようになる。
上記の中で、Lxx/Lyy などは、行数などの目安
こうして実行すると、必要なサブルーチンの実行順やネスティングの状態、ポイント毎の変数値などの推移、そしてその対応したコードの位置までが分かってデバッグがかなりやりやすくなる。 また、各代入文の $teststr .= "・・・・"; は実際の運用時に残っていても邪魔になることはないが、
print "TESTSTRINGs are : $teststr";
だけは実際の画面に表示されるので、削除しないとかっこ悪い。しかし、ユーザからこんな問題がある、と言われることも考えると 以下のようにして残しておくと良い。
print "<!--- TESTSTRINGs are : $teststr --->";
こうすることで、このテスト文字列が実際の画面には表示されないが、ウィンドウ上で 右クリックして「ソースの表示」を選択すれば 必要な文字列が表示されるので、もし必要があれば頼んでその部分を教えてもらうとか、運用中にも自分で確認することが出来る。
最近の高級言語は、開発環境が整っており、コードを書いてデバッグする際に実行をトレースしたり、変数値をウォッチしたり出来ることが普通になっている。それに比べると フリーウェアで構築できる Perlの開発環境は(私が知る限り)、一切そうした事が出来ない。殆どの場合、サーバーエラーが返されるか、コマンドプロンプトから perl -cw (スクリプトパス) と打ち込んで、問題のある行を表示させることが精一杯。文法エラーがなくて動作はするが、表示がおかしいと言うような場合、コード見ながら変数値やサブルーチンを追いかけるのは非常に大変。
そんな時、私は以下のようにやっている。
メインルーチンで、まず グローバルな文字列変数を定義する。そしてプログラムの要所要所(サブルーチンの頭とか、if文の中)で、その変数に サブルーチンの名前や 変数値を結合していき、HTML出力の最後の方で その文字列変数を プリントする。
実際には以下のようになる。
#!/usr/bin/perl $teststr; ・ ・ if ($aaa <= 10 ) { $teststr .= "Lxx \$aaa : $aaa \|" ・ } ・ print "TESTSTRINGs are : $teststr"; ・ print "</body> </html>"; exit; sub routinA { $teststr .= "Lyy sub routinA / <BR>"; ・ ・ } |
こうして実行すると、必要なサブルーチンの実行順やネスティングの状態、ポイント毎の変数値などの推移、そしてその対応したコードの位置までが分かってデバッグがかなりやりやすくなる。 また、各代入文の $teststr .= "・・・・"; は実際の運用時に残っていても邪魔になることはないが、
print "TESTSTRINGs are : $teststr";
だけは実際の画面に表示されるので、削除しないとかっこ悪い。しかし、ユーザからこんな問題がある、と言われることも考えると 以下のようにして残しておくと良い。
print "<!--- TESTSTRINGs are : $teststr --->";
こうすることで、このテスト文字列が実際の画面には表示されないが、ウィンドウ上で 右クリックして「ソースの表示」を選択すれば 必要な文字列が表示されるので、もし必要があれば頼んでその部分を教えてもらうとか、運用中にも自分で確認することが出来る。
デスクトップ機で通常は Perlの編集には Eclipse を使っていたがコンパイラを使用しない Perlの編集だけに Eclipseを Noteにインストールするのは大げさ・・と思って、改めてスクリプトエディタを探してみると、Atomエディタという汎用のコードエディタが Perlスクリプトにも便利そう。
とりわけ 「Ctrl+Shift+p > Ctrl+Shift+b」で Perlが実行できて、エラーやワーニングが表示されるので文法チェックが可能だ。
とりわけ 「Ctrl+Shift+p > Ctrl+Shift+b」で Perlが実行できて、エラーやワーニングが表示されるので文法チェックが可能だ。