15←  home  →17
16 1999年8月1日

Perlは楽しい(2)

Perlの話は一息いれるはずだったのに、もういっちょプログラムが出来たので、お調子者ぶりを発揮して発表しようかなあ、と。

今度は、左側のフレームにある「雑記」の新しいリンクの作り方です。わたし面倒くさがる方で、一つずつリンクを書いていくのは気が重い。というのでこれまでほったらかしてきましたが、これもPerlを使えば楽が出来るのでは?と思いやってしまいました。

これまでは、プログラムを出して解説してましたが、今回は「いかにプログラムを作成したか」という話の展開をしようかな、と。
 

作りたいのは例えば

<p><a href='zakki_010.html'>雑記(10)</a>
<p><a href='zakki_011.html'>雑記(11)</a>
<p><a href='zakki_012.html'>雑記(12)</a>

のように1つづつ数が増加していけばいいわけですから、それで使えそうな関数っていうんですか、手法を探せばいい、ということで「とほほ」のPerl説明書を眺めていたら、
 
 

while文

while(...)は、(...)が真のあいだ{...}を繰り返します。
    $xx = 1;
    while ($xx < 10) {
        print "xx = $xx\n";
        $xx++;
    }

というのが使えそうです。$xx++;というのは変数に1を足すという意味です。それでこの部分は解読できるでしょう。変数を、1から始め、10以下の間は、printしては1を加えていくという処理です。つまり

1
2
3
4
5
6
7
8
9

とprintされて行くわけです。あちゃ10は表示されんのか!と実際に気がついたのはプログラムを作ってからでした。(馬鹿なわたし)
 
 
 

until文

until(...)は、(...)が真になるまで{...}を繰り返します。

    $xx = 1;
    until ($xx > 10) {
        print "xx = $xx\n";
        $xx++;
    }

というのがあります。これだと10まで作ってくれます。よかったよかった。
これで核心部分の目途ができました。

<p><a href='zakki_010.html'>雑記(10)</a>
<p><a href='zakki_011.html'>雑記(11)</a>
<p><a href='zakki_012.html'>雑記(12)</a>

の可変部分でuntil文を使えばいいのです。

わたしは最初は上の構文をほぼそのまま使いました。とりあえず、$numberという変数を使って(勝手に決めるのです)、指定した数字、例えば20なら1〜20まで連続させることにしました。こんなヤツです。
 
$xx = 1;
until ($xx > $number) {
      print HTML "<p><a href='zakki_0$xx.html'>雑記($xx)</a>\n";
      $xx++;
}

でまあ、出来たんですが、次もまたまた1〜希望する例えば30まで作るのも馬鹿みたい。
ということで、指定された数から数まで作るようにしたいなあ、ということで、2つ変数を使うことに変更。
from me to you ということで $number_f と$number_t と名付けました。例えば、from 20 to 30 なら、20が30になるまで、表示しては1を足して、を繰り返せばいいのですから

until ( $number_f > $number_t){
        print HTML "<p><a href='zakki_0$number_f.html'>雑記($number_f)</a>:Coming soon\n";
      $number_f ++;
}

でいいわけです。初稿にはなかった:Coming soon などというオマケも付けてみました。ところでやってみればわかるのですが、10以下なら、zakki_02となります。実際のファイルはzakki_002になってるので困ります。ということで、その処理が加わり、実際は

until ( $number_f > $number_t){
    if ($number_f <10 ){
    print HTML "<p><a href='zakki_00$number_f.html'>雑記($number_f)</a>:Coming soon\n";
} else {
    print HTML "<p><a href='zakki_0$number_f.html'>雑記($number_f)</a>:Coming soon\n";
}
    $number_f ++;
}

というプログラムにしました。次は2つの変数を送るHTMLを作ります。といっても、前回の「Perlは楽しい」で作ったのを改造すれば終わりです。
 
 
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
   <title>renban wizzard</title>
</head>
<body bgcolor="#CCCCCC" onLoad="document.form.number_f.focus()">
<font color="#990000"><font size=+3>連番linkウィザード</font></font>
<p>
<hr>
開始番号と終了番号を半角数字で入力して下さい。
<p><form NAME="form" ACTION="zakki_index.cgi" METHOD="post">
from <input TYPE="text" SIZE=5 NAME="number_f">to<input TYPE="text" SIZE=5 NAME="number_t">
<p><input TYPE="submit" VALUE=" 書き込む "><input TYPE="reset" VALUE=" 取り消す "><INPUT TYPE="hidden" NAME="myaction" VALUE="write">
</form>
<hr>
</body>
</html>

を表示すると
 
連番linkウィザード


開始番号と終了番号を半角数字で入力して下さい。

from to


のようになります。

後は、出力するHTMLファイルの方をきっちり作ればいいのですが、これは、私はもうcomposerで例えば次のような雛形を作って、
 
雑記index

雑記(10)
 

それをテキストとして読むと
 
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
   <meta name="GENERATOR" content="Mozilla/4.6 [ja] (Win98; I) [Netscape]">
   <title>zakki_index</title>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
<font size=+3>雑記index</font>
<p><a href="zakki_010.html">雑記(10)</a>
</body>
</html>

のようになりますので、これを改造して使います。テキストエディタで1からHTMLファイルを作ることはしてません。

あとはもう、前回の「Perlは楽しい」と同じ手法で作れるのですが、それでは芸がないので、新手法を使いました。formで、hiddenを使い、あとサブルーチンも作って見ました。

hiddenというのは、cgiに情報を送る箇所で、

<INPUT TYPE="hidden" NAME="action" VALUE="write">

と指定します。NAME, VALUEの名前は任意で付けます。hiddenですから画面には表示されませんが、情報が送られる場合には、actionがwriteだよ、と送られます。

これくらいでプログラムの解説(やっぱやるんじゃないか!)

あ、脱線して、こんな解説を書いている一つの理由。時間がたったら自分が忘れる!いや本当です。以前Dosの時代の代表的データベースソフトで桐というのがあるんですが、その「一括処理」というプログラムの一種を書いて半年後ぐらいに読むと何やってんのか分からない!いや冗談じゃなくて自分で書いたプログラムが自分で読めないんです。HTMLだって「あれ?どうだったっけ?」ということで自分が書いた「入門」を読み返したことがもうあります。Perlだって今は覚えているけど後で「あれ?」って絶対なる自信があります。はは・・・(乾いた笑い)
 
 
 
# 漢字ライブラリの読み込み
require "jcode.pl";

# 初期化
&init_form(sjis);

# ヘッダの送出
print "Content-type: text/html\n\n";

$action   = $form{'action'};

# メインプログラム
if ($action eq "") {
 &get_number;
} else {
 &make_file;
}
# 終了
exit(0);
 

# サブルーチン
# 書き込み用HTMLを出力する
sub get_number {

print <<"end_of_form";

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
   <title>renban wizzard</title>
</head>
<body bgcolor="#CCCCCC" onLoad="document.form.number_f.focus()">
<font color="#990000"><font size=+3>連番linkウィザード</font></font>
<p>
<hr>
開始番号と終了番号を半角数字で入力して下さい。
<p><form NAME="form" ACTION="zakki_index.cgi" METHOD="post">
from <input TYPE="text" SIZE=5 NAME="number_f">to<input TYPE="text" SIZE=5 NAME="number_t">
<p><input TYPE="submit" VALUE=" 書き込む "><input TYPE="reset" VALUE=" 取り消す "><INPUT TYPE="hidden" NAME="action" VALUE="write">
</form>
<hr>
</body>
</html>
end_of_form

}

# 送られた数字を処理しHTML作成
sub make_file {

# 情報の取得
$number_f  = $form{'number_f'};
$number_t  = $form{'number_t'};
 

# ファイルを開く
open (HTML, ">zakki_index.html");

# ファイルに出力
print HTML <<"end_of_html";
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
   <title>zakki_index</title>
</head>
<body bgcolor="beige">
<font size=+3>雑記index</font>
end_of_html

until ( $number_f > $number_t){
    if ($number_f <10 ){
    print HTML "<p><a href='zakki_00$number_f.html'>雑記($number_f)</a>:Coming soon\n";
} else {
    print HTML "<p><a href='zakki_0$number_f.html'>雑記($number_f)</a>:Coming soon\n";
}
    $number_f ++;
}
print HTML "<br>\n</body>\n</html>\n";

# ファイルを閉じる
close (HTML);

# 報告
# print "Content-type: text/html\n\n";
print "<h1>OK</h1>";
print "<h1>zakki_index.html が生成されました。</h1><br>";

}
 

# フォームからの情報を連想配列 %form に入れる
# Copyright (C) 1997 by Hiroshi Yuki.
# &init_form('euc');
sub init_form {
    local($query, @assocarray, $assoc, $property, $value, $charcode, $method);
    $charcode = $_[0];
    $method = $ENV{'REQUEST_METHOD'};
    $method =~ tr/A-Z/a-z/;
    if ($method eq 'post') {
        read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
    } else {
        $query = $ENV{'QUERY_STRING'};
    }
    @assocarray = split(/&/, $query);
    foreach $assoc (@assocarray) {
        ($property, $value) = split(/=/, $assoc);
        $value =~ tr/+/ /;
        $value =~ s/%([A-Fa-f0-9][A-Fa-f0-9])/pack("C", hex($1))/eg;
        &jcode'convert(*value, $charcode);
        $form{$property} = $value;
    }
}
 

じゃ、はじめから

# 漢字ライブラリの読み込み
require "jcode.pl";

# 初期化
&init_form(sjis);

# ヘッダの送出
print "Content-type: text/html\n\n";

ここまではOKですよね。定番です。
 

$action   = $form{'action'};

ここでhiddenで送られてきたのを一応$actionに入れてます。
 

# メインプログラム
if ($action eq "") {
 &get_number;
} else {
 &make_file;
}
# 終了
exit(0);

これだけでプログラム終わり。ははは。そんだけサブルーチンがでかいということですが。。。

サブルーチンは勝手に作ります。

sub 名前 {
処理を記述
}

で作れちゃいます。呼び出すときは、&名前で行います。

ですから、上の部分は

$action が空だったら、&get_numberというサブルーチンをしなさい。
以外なら、&make_fileというサブルーチンをしなさい。
終わり

ということです。「$action が空だったら」と、いうことは、まだ数字が送られていなかったらということです。
その場合の処理が次のサブルーチンです。

# サブルーチン
# 書き込み用HTMLを出力する
sub get_number {

print <<"end_of_form";

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
   <title>renban wizzard</title>
</head>
<body bgcolor="#CCCCCC" onLoad="document.form.number_f.focus()">
<font color="#990000"><font size=+3>連番linkウィザード</font></font>
<p>
<hr>
開始番号と終了番号を半角数字で入力して下さい。
<p><form NAME="form" ACTION="zakki_index.cgi" METHOD="post">
from <input TYPE="text" SIZE=5 NAME="number_f">to<input TYPE="text" SIZE=5 NAME="number_t">
<p><input TYPE="submit" VALUE=" 書き込む "><input TYPE="reset" VALUE=" 取り消す "><INPUT TYPE="hidden" NAME="action" VALUE="write">
</form>
<hr>
</body>
</html>
end_of_form

}

何のことはない、上で載せたHTMLファイルを全部出力するだけです。

これで入力画面が表示されますから、数字を書いて送ります。送るときはaction=writeで送られますから
elsif ($action eq 'write')でもいいんですが、面倒だったので、elseでおしまい。

で次が数字が送られてきた時のサブルーチン。
 

# 送られた数字を処理しHTML作成
sub make_file {

# 情報の取得
$number_f  = $form{'number_f'};
$number_t  = $form{'number_t'};
 

# ファイルを開く
open (HTML, ">zakki_index.html");

# ファイルに出力
print HTML <<"end_of_html";
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
   <title>zakki_index</title>
</head>
<body bgcolor="beige">
<font size=+3>雑記index</font>
end_of_html

until ( $number_f > $number_t){
    if ($number_f <10 ){
    print HTML "<p><a href='zakki_00$number_f.html'>雑記($number_f)</a>:Coming soon\n";
} else {
    print HTML "<p><a href='zakki_0$number_f.html'>雑記($number_f)</a>:Coming soon\n";
}
    $number_f ++;
}
print HTML "<br>\n</body>\n</html>\n";

# ファイルを閉じる
close (HTML);

# 報告
# print "Content-type: text/html\n\n";
print "<h1>OK</h1>";
print "<h1>zakki_index.html が生成されました。</h1><br>";

}
 

ここもほとんとHTMLファイルがそのまま利用されてますね。ファイルを開くとかはもう前回の「楽しい」で説明してますから省略します。

あと「とほほ」を読むと
 
 

for文

for(...)は指定回数処理を実行する際に用います。次の例は最初に$xxに1を代入して、$xxが10以下であるあいだ、$xxを1ずつ加算しながら、printを実行することを意味します。
    for ($xx = 1; $xx <= 10; $xx++) {
        print "xx = $xx\n";
    }
次の構文も上と同じ動作をします。
    @xx = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    for (@xx) {
        print "xx = $_\n";
    }
また、次の構文も同様です。

    for (1..10) {
        print "xx = $_\n";
    }

 

というのも使えそうですが、10以下の処理がやりにくそうなので使いませんでした。動きゃいいもんね。
 



地球滅亡の日の次の日の更新でした。

15←  home  →17