ここ何回か複数のユーザに対応すべくいろいろとやってきましたが、いっそのことユーザ名とパスワードを別のファイルにまとめておきましょう。 そうすればユーザ登録やパスワードの変更時にいちいちスクリプトを変更しなくてもすみます。 「事務は事務方に」というわけです。
まずメモ帳などで次のようなファイルを作成します。
can,nyanko
masa,wanko
hide,buhibuhi
ファイル名はuser.datとしておきます。
では,この事務方ファイルを使って改造版を作りましょう。 このファイルをスクリプトに読みこませるには、まずファイルを開かなければいけません。 Perlではファイルを開くための関数としてopen関数があります(わかりやすぅ〜)。
open(IN, "<user.dat");
( )内を見るとまずINとあります。 これはファイルハンドルといって,スクリプトとデータファイルを結びつけるものです。 スクリプトはこのファイルハンドルを通じてuser.datというファイルを読んだり書いたりします。 ファイルハンドルは大文字で書く習慣になっています(他の変数名などとぶつからないようにするため)。
ファイルハンドルのあとにダブルクォートで囲んでファイル名がありますが,その前に<があります。 これはファイルを「読取専用」として開くことを表しています。
ファイルを開いたら,その中のデータを読み込みましょう。
@data = <IN>;
と書きます。 これによって、ファイルハンドルINによって結び付けられたuser.datの中身を,改行までを一つの要素と見て配列@dataに代入します。 今の場合,
$data[0] = 'can,nyanko\n';
$data[1] = 'masa,wanko\n';
$data[2] = 'hide,buhibuhi';
となります。
ここで一つ種明かしをします。 今まで何度も、
$username = <STDIN>;
と書いてきました。 実はSTDINというのは標準入力(普通はキーボード)に与えられた特別なファイルハンドルなんです。 そして上のように書くことで,キーボードからの入力を,Enterキーが押されるまで受け取って,$usernameというスカラー変数に代入するように命令していたんです。
さて最後,ファイルからデータを読み取ったらファイルを閉じましょう。 これもわかりやすく、
close(IN);
と書きます。 なんとも直感的ですね。
では,改造版スクリプトです。
01: open(IN, "<user.dat"); #ファイルオープン
02: @data = <IN>; #データを読み込んで
03: close(IN); #ファイルクローズ
04: foreach(@data){
05: ($name, $passwd) = split(/,/, $_);
06: chomp($passwd);
07: $passwd{$name} = $passwd;
08: }
09: print "あなたのお名前なんてーの?:";
10: $yourname = <STDIN>;
11: chomp($yourname);
12: $namecheck = 0;
13: foreach $username (keys %passwd) {
14: if($yourname eq $username){
15: $namecheck = 1;
16: print "よっ、$yournameちゃん、どう?最近。\n";
17: $pwdcheck = 0;
18: for($j = 0; $j < 3; $j = $j + 1){
19: print "パスワード入力:";
20: $yourpasswd = <STDIN>;
21: chomp($yourpasswd);
22: if($yourpasswd eq $passwd{$username}){
23: print "OK. 入ってイイよ〜\n";
24: $pwdcheck = 1;
25: last; #forループから脱出(A)
26: } else{ #条件式が偽の場合ここを実行
27: print "おや、パスワード間違えた?\n";
28: }
29: }
30: #(A)ここへ出てくる
31: } else{
32: next; #次のループへ(B)
33: }
34: if(($namecheck == 1) && ($pwdcheck == 1)){
35: last; #名前もパスワードも一致したら(C)
36: } elsif($pwdcheck == 0){
37: print "ムム、お主何やつ!\n";
38: }
39: #(B)ここへ移動して次のループへ
40: }
41: #(C)ここへ移動
42: if($namecheck == 0){
43: print "あれ? 名前が登録されてないよ。\n";
44: }
スクリプトを見ていきましょう。 1行目でuser.datを開いて,2行目でデータを読み込んで,3行目でファイルを閉じています。 これは上で説明したとおりですね。 4行目。 前回も登場したforeachループですが,チョット変です。 foreachループの構文は,
foreach $val (@array){
実行文;
}
となっていました。 そして、@arrayの要素を順に1つずつ$valに代入して,それに対して実行文を実行します。 ですが,上のスクリプトの4行目には$valにあたる部分がありません。 でも安心してください。 Perlの書き方はこれでもOKです。 foreachループでこの$valにあたる部分を省略した場合,Perlは特別なスカラー変数$_というのを用意していて,そこへ代入して処理をします。 ああ、Perlよ、君はなぜそんなにおおらかなんだ!
5行目を見てください。 新しい関数splitが登場しました。 ( )内を見ると,最初に/,/とあり,そのあとに$_とあります。 split関数は,$_の中を見て,そこに/で挟まれた文字(ここではカンマ)を見つけると,その前後を区切ってくれます。 もう少し詳しく言うと,まずこの時点で$_には、
can,nyanko\n
という文字列が入っています。 split関数はこの文字列を見て,カンマ(,)を見つけると,その前後,つまりcanとnyanko\nを区切ってくれます。 そしてそれぞれを左辺の変数に代入してくれるのです。
6行目。ここで$passwdの最後にある改行文字を除いて7行目でハッシュ%passwdに値をセットしています。 このforeachループによって,前回作成した%passwdと同じ物が出来たことになります。 あとはスクリプトには変更はありません。
さて、第1章も大詰めです。 次回は「スクリプト内アウトソーシング」についてお話します。