last-modified: 2nd/June/'01;
since: 1st/June/2001;
前節では while によるブロックの繰り返しと、 last による繰り返しからの脱出を紹介しました。
次に、パスワードのトライを三回迄に限定するように修正してみましょう。
while で繰り返す場合は、二つの方法が考えられます。
何れの場合も、繰り返した回数を蓄えておく変数が新たに必要になります。まず、 last を用いて繰り返しを脱出するように修正します。
前節のスクリプトの、 10 行目から 18 行目だけを修正します。
idpass2.pl>>
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: |
$counts = 1;
while (1) {
chomp($pass = <STDIN>);
if ($pass eq $login_pass) {
print "パスワードが確認されました。\n";
last; # while から抜け出し
} else {
if ($counts == 3) {
print "パスワードの認証に失敗しました。\n";
last;
} # 「if 文」終了
$counts++;
print "もう一度パスワードを御願いします; ";
} # 「if 文」終了
}
|
6 行目と 10 行目の last が繰り返しを脱出する組み込み函数です。スクリプトの実行自体を終了する場合は exit です。
別法として、繰り返しの回数を 3 回に指定する方法もあります。
無限繰り返しのスクリプト idpass.pl の 10 行目の繰り返し while の前後を、次のように書き換えます;
idpass3.pl>>
1: 2: 3: 4: 5: |
$i = 1;
while ($i < 3) {
$i++;
...省略...
}
|
1 行目
カウントの回数を表す変数 $i の初期値を指定しています。
2 行目
while の条件式は、繰り返し回数が 3 未満ならば更に繰り返す事を意味しています。
3 行目
繰り返しブロック内部で、繰り返し変数を一つ増やします。 $i = $i + 1; の省略形です。
4 行目以降
繰り返しブロック内部は省略しました。
このような使い方には、 while 文よりも for 文の方が向いています。 for 文の構文は C の for 文と同じです。
無限繰り返しのスクリプト idpass.pl の 10 行目を、次の例の 1 行目に書き換えるだけです。
idpass4.pl>>
1: 2: 3: |
for ($i = 0; $i < 3; $i++) {
...省略...
}
|
for 文の基本構文は次のようになります;
for (初期化式; 比較式; 終端式) {
ブロック
}
初期化式は、 for ループを実行する前に実行する文です。通常は繰り返し回数を表す変数の初期値を定義します。
比較式は、繰り返しを継続する条件式です。通常は繰り返し回数を表す変数の上限を定義します。この式が真 (true) であれば繰り返し、偽 (false) になるとブロック内の処理を飛ばして、次の行へ制御が移ります。
終端式は、繰り返し内容を一回実行する度に実行します。通常は繰り返し回数を表す変数を、ループ一回事にいくつ増やすか定義します。
これを while 文で実現すると、次のようになります。
初期化式;
while (比較式) {
ブロック
} continue {
終端式;
}
Perl の演算子では、数値が等しい場合は ==、文字列が等しい場合は eq を用います。因みに、 = は代入演算子です。
| 数値 | 文字列 | 意味 |
|---|---|---|
== | eq | 等しい |
!= | ne | 等しくない |
< | lt | より小さい |
> | gt | より大きい |
<= | le | 以下 |
>= | ge | 以上 |
<=> | cmp | 比較 |
Perl スクリプトでは、文字列と数値に区別がないので、比較する目的に応じて、演算子の方を書き換えているわけです。
文字列の大小比較は、先頭から順に文字コードで比較します。例えば、数字の場合、数値として扱えば 2 < 13 ですが、文字列として扱うと 2 gt 13 になります。
10 <=> 3 | -1 |
10 <=> 100 | 1 |
10 <=> 10 | 0 |
<=>, cmp の場合は、右辺が小さければ 1、逆ならば -1、等しい時には 0 を返します。