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
を返します。