§1.5 嬉しい悩み


作成日:2001/05/29(月)

今までにユーザ名とパスワードを受け取って、それぞれ判定をして簡単な認証のようなモノを作ってきました。 でもこれまではユーザーはただ1人でしたね。 ここでもし、「俺も入れてくれよ」という人がいたらどうしましょう。 自分が書いたスクリプトを多くの人が使ってくれるのはプログラマーでなくてもとても嬉しいものですが、そのたびにユーザー名とパスワードを格納する変数を用意するのはとても大変ですよね?
 でも安心してください。 このような場合にもPerlはちゃんと備えています。 それが「配列」です。 配列とは簡単に言うと「スカラー(数値や文字列等)がいっぱい乗った台車」のようなもので、個々の要素はインデクスと呼ばれる0から始まる数字で管理されます。

配列はスカラー変数がいっぱい乗った台車

ではまずユーザ名とパスワードをあらかじめ決めておきましょう。

番号
(インデクス)
ユーザ名 パスワード
0 can nyanko
1 masa wanko
2 hide buhibuhi

 では、スクリプトを見てみましょう。

 01: @username = ('can', 'masa', 'hide'); #ユーザ名をセット
 02: @passwd = ('nyanko', 'wanko', 'buhibuhi'); #パスワードをセット
 03: print "あなたのお名前なんてーの?:";
 04: $yourname = <STDIN>;
 05: chomp($yourname);
 06: $namecheck = 0;
 07: for($i = 0; $i <= $#username; $i = $i + 1) {
 08:   if($yourname eq $username[$i]){ 
 09:     $namecheck = 1;
 10:     print "よっ、$yournameちゃん、どう?最近。\n";
 11:     $pwdcheck = 0;
 12:     for($j = 0; $j < 3; $j = $j + 1){
 13:       print "パスワード入力:";
 14:       $yourpasswd = <STDIN>;
 15:       chomp($yourpasswd);
 16:       if($yourpasswd eq $passwd[$i]){
 17:         print "OK. 入ってイイよ〜\n";
 18:         $pwdcheck = 1;
 19:         last; #forループから脱出(A)
 20:       } else{ #条件式が偽の場合ここを実行
 21:         print "おや、パスワード間違えた?\n";
 22:       }
 23:     } 
 24:   #(A)ここへ出てくる
 25:   } else{
 26:     next; #$iを1増やして次のループへ(B)
 27:   }
 28:   if(($namecheck == 1) && ($pwdcheck == 1)){
 29:     last; #名前もパスワードも一致したら(C)
 30:   } elsif($pwdcheck == 0){
 31:     print "ムム、お主何やつ!\n";
 32:   }
 33: #(B)ここへ移動して次のループへ
 34: }
 35: #(C)ここへ移動
 36: if($namecheck == 0){
 37:   print "あれ? 名前が登録されてないよ。\n";
 38: }

まず1、2行目。 配列にユーザ名とパスワードを格納します。配列にデータを格納するには、スカラー変数と同様代入演算子=を使います。 右辺には格納する個々のデータをカンマ( , )で区切って、全体を( )で囲んで並べます。
 6行目。 $namecheckに0をセットします。 これはユーザ名が登録済みならば1に変更されます。 そして7行目からのforループで、ユーザ名のチェックが行われます。 この条件式には、

 $i <= $#username

と書いてあります。 まず<=演算子は数学の「小なりイコール」と同じ意味で、演算子の左側の値が右側の値よりも等しいか小さければ真となります。 そしてその次の$#usernameは、配列@usernameの最後のインデクスを表しています。 今の場合、@usernameには3つのデータが格納されていますが、先ほども説明したとおり、配列のインデクスは0から始まるので、$#usernameの値は2になります。つまり、「$iが2以下ならば真」ということです。
 8行目のif文の条件式を見てください。 配列の個々のデータにアクセスするときには$username[0]や$username[$i]のように、アクセスしたいデータのインデクスを[ ]で囲んで指定します。 先頭の文字が@ではなくて$であることに注意してください。 配列のインデクスにはスカラー変数の値を使うことも出来ます。 今の場合$iはforループの制御のために使われている変数で初期値は0です。 @usernameのインデクス0,つまり最初のデータはcanなので、この条件式は、

 $yourname eq 'can'

と同じ意味になります。 そして$iは2以下なので、0,1,2という具合に順番にセットされ、条件が次々に変わっていきます。 こうして入力されたユーザ名と登録済みのユーザ名を1つ1つチェックしていくのです。
 ユーザ名が一致したらパスワードチェックに移ります。 この部分は前節と変更はありません。
もしユーザ名が一致しなかった場合は26行目のelse節に飛びます。 そこにはたった一言、

 next;

とあります。 このnext関数は,ループ内の以下の処理を中止して次のループへ移ります。 今の場合27行目以降の処理を中止して33行目に移動し、$iの値を1増やして次のループに移ります。
 28行目。 if-elsif文が出てきました。 今までのif文では2者択一の条件分岐しか出来ませんでしたが、if-elsif文では、まずifの条件がチェックされ,それが偽ならば今度はelsifの条件がチェックされます。 elsifの部分をたくさん書けば、もっと細かく分岐させることも出来ます。 今の場合,まず28行目、

 if(($namecheck == 1) && ($pwdcheck == 1))

とあります。 ここで新しい演算子&&が出てきていますが,これは数学の「かつ」といっしょで,その前後の条件が両方とも正しいときだけ真となります。 上の条件は,ユーザ名とパスワードが両方とも一致したときに真になります。 もしこの条件が偽なら、

 elsif($pwdcheck = 0)

をチェックします。 つまりパスワードが3回とも一致しなかった場合です。
 あとはユーザ名が未登録の場合の処理です。 このスクリプトを実行すると、

 あなたのお名前なんてーの?:hide
 よっ、hideちゃん、どう?最近。
 パスワード入力:nyanko
 おや,パスワード間違えた?
 パスワード入力:buhibuhi
 OK. 入ってイイよ〜

のようになります。


「§1.4 Give me a chance」へ 「§1.6 続・嬉しい悩み」へ
ソフトバンク パブリッシング株式会社

Copyright (C) can All Rights Reserved
e-mail:ishiki@mrj.biglobe.ne.jp