まず最初に断っておきますが、このスクリプトは大したものじゃありません。なので、あまりPerlの勉強にはならないかもしれません。まあ、私自身もそれほどPerl使いなわけでもありませんし。(^^;)
それと、プログラミングの初心者は対象にしていません。とりあえず読んでみて、わけがわからないと思ったら修行してから再度読み直してみてください。すみません。
ここで示すのは、メインメニューで使われている更新事項列挙のスクリプトです。まあ、まずはソースから見ていきましょう。
01: if( !open UPDATE, "<update.inf" )
02: {
03: @UpdateInfo = ("<FONT color=red>更新情報ファイルがありません.</FONT>");
04: }
05: else
06: {
07: @color = ( "#ffffff", "#dddddd", "#cccccc", "#aaaaaa", "#999999", "#888888", "#777777", "#666666" );
08: foreach $color ( @color )
09: {
10: last if !($line = <UPDATE>);
11: chomp $line;
12: @line = split( /,/, $line );
13: next if $#line < 2;
14: $str = sprintf "<FONT color="%s">%04d/%02d/%02d", $color, @line;
15: $str = $str . " - $line[3]</FONT>\n";
16: push( @UpdateInfo, $str );
17: }
18: close UPDATE;
19: }
先頭の行番号は便宜上つけただけです。ソースコードの一部ではありませんので。……って、それくらいわかりますよね。
このスクリプトはファイルupdate.infから更新情報を読み取り、それを整形してHTMLとして出力する、ということを行います。メインメニューの上部で使われているのがわかりますよね。
では、解説に入ります。
1行目のopenでupdate.infからデータを読み込めるようにします。ファイル名の前に'<'が付いていますが、Perlではこのようにしてアクセスモードを指定します。C言語のfopenとは異なるところに気をつけてください。逆の向きにすれば出力になります。
openの最初の引数にUPDATEというものがありますが、これはファイルハンドルです。C言語でいえばFILE構造体のようなものです。このようにして、ファイルupdate.infをファイルハンドルUPDATEに割り当てます。
3行目で@UpdateInfoが突然使われていますが、PerlではC言語と違って変数を前もって宣言する必要がありません。BASICのようで楽といえば楽なのですが、バグの温床ともなっています。タイプミスには十分気をつけましょう。
また、()で値を囲んでいますが、丸かっこで囲まれてカンマで区切られた文字列や数値の列をリストといいます。そして@で始まる変数は配列を表します。この場合は配列変数にリストを代入しているわけです。リストを代入すると、配列の各要素にリストがコピーされます。
7行目でも配列変数にリストを代入しています。
ところで、2行目〜4行目はifの条件が真の時に実行される部分ですが、C言語と異なりたとえ一文だけしかない場合でも{と}を省くことはできません。これは時々すっかり忘れてしまうことなので、よく覚えておいてください。if文に限らず、while文などでもこの規則は当てはまります。
8行目のforeachはC言語にないので、初めて見る人もいるでしょう。foreachは渡された配列の各要素をスカラー変数に代入しながらループするというforです。つまり、カウンタを使って配列の各要素を見ていくforと同じようなものです。
スカラー変数という言葉が出てきましたが、これに関しては後で説明します。
10行目もC言語では見られない形です。
lastはC言語でいうbreakです。現在実行しているループを抜ける役割を果たします。また、lastの直後にifが続いていますが、これは「if以下が真の場合ifの前を実行しろ」という意味です。この場合は、ファイルupdate.infからデータが読み込めなくなったらループを終了するということになります。
<UPDATE>という書き方がありますが、これはUPDATEに割り当てられたファイルからデータを一行読み込む、というものです。その読み込んだデータはスカラー変数$lineにコピーされています。ファイルの末尾まで読み込んでしまった場合は空文字列が返されるので、!演算子によりif以下が真になります。
そういうわけで、この行はファイルからデータが読み込めなくなったらループを終了するということになるのです。
11行目のchompは文字列の末尾にある改行文字を取り除く関数です。ファイルから読み込んだ場合、文字列には改行文字も含まれているので、この関数を使って取り除きます。改行文字がない場合は何も行いません。
12行目のsplit関数は変数を指定された文字列で区切り、リストにするという関数です。update.infの各行はカンマで区切られているので、このような書き方になります。リストに分割するのは、データにアクセスしやすくするためです。繋がったままだったとすると、とても扱いにくいですよね?
カンマをスラッシュで囲っていますが、この部分には正規表現を使うことができるのでこのような形式になっています。正規表現に関しては、また後で詳しく解説します。
13行目も10行目と同じ後置if文を使っています。$#lineというものがありますが、これは「配列の最終要素のインデクスを得る」というものです。つまりこの場合、@line配列の最後にある要素のインデクス番号になります。通常、update.infの各行にはカンマで区切られた三つのデータが並んでいます。なので@lineには少なくとも三つの要素があります。@lineに三つ未満の要素しかない場合、それは処理できないので後の処理を行わずにループの先頭に戻らなければなりません。
nextというキーワードは、ループの先頭に戻るという処理を行います。ループを終了してしまうlastと比較してください。
14行目では関数sprintfを使っています。これはC言語のsprintfと同じで、バッファに書き込むのではなく、結果をスカラー値として返すというところが異なっています。ここではデータを整形するのに使用しています。フォーマットの書式はC言語のものと同じです。
15行目にあるドット演算子は、C言語の構造体アクセスとは違います。Perlでは、文字列を連結するためにドット演算子を使用します。プラス演算子では数値として解釈され、計算されてしまいます。文字列のまま連結したい場合はドット演算子を使用します。
16行目のpush関数は、配列の末尾にスカラーを追加します。C++にあるSTLコンテナのpush_backと同じですね。
9〜17行目のループが終了したら、もうupdate.infは必要ありません。開いたファイルは閉じておかなければならないので、close関数を使ってUPDATEファイルハンドルを解放します。closeしなくても、Perlが終了したときに自動的に閉じてくれることになっていますが、間違って使ってしまったときの被害を出さないようにするため、ちゃんと閉じておいた方が好ましいでしょう。
こんなものです。実際に使う機能や関数は限られていますので、覚えなければならないことはあまり無いでしょう。しかし凝ったことをやろうとすると、やはりリファレンスが必要となってきます。リファレンスはオンラインのものを使ったり、書籍を購入したりして対処してください。さすがにここではできません。
書籍としては、「Perlスクリプティング入門」内田保雄/富田満・共著、オーム社開発局がお勧めです。日本人が書いているので文章がわかりやすく、とりあえず必要なものはほとんど網羅されています。これを読めば、ここに来る必要はないでしょうね……。(^^;)
さて、後で解説するといったスカラー変数と正規表現に関して補足しておきます。
スカラー変数は数値、文字列といったリテラルのことを示します。配列や連想配列(Perl5からはハッシュ)はスカラーではありません。ハードリファレンスなどのポインタもスカラー変数として扱われます。
また、スカラー変数は先頭の一文字に$を付けて区別します。他のものも示すと配列は@、ハッシュは%を使います。ファイルハンドルは何もつけませんが、慣例的にすべて大文字の名前を使います。それぞれの名前空間は分けられているので、$hogeと%hogeは違うものとして扱われます。
正規表現ですが、これはそう簡単に解説できるようなものではありません。オートマトンを習っている人ならば楽にわかると思うのですが……。とりあえずいくつかの文字列を表現するために使うキーワードのようなものだと考えればよいでしょう。正規表現の書式はPerlのドキュメントに書いてありますし、ほかのサイトに解説しているところがあるでしょう。サーチエンジンで「正規表現」をキーワードにして検索してみてください。