繰り返しからの脱出

last-modified: 2nd/June/'01;
since: 1st/June/2001;

前節では while によるブロックの繰り返しと、 last による繰り返しからの脱出を紹介しました。

次に、パスワードのトライを三回迄に限定するように修正してみましょう。

while で繰り返す場合は、二つの方法が考えられます。

  1. 3回トライしたら繰り返しを脱出。
  2. 繰り返しを3回までに指定して作成。

何れの場合も、繰り返した回数を蓄えておく変数が新たに必要になります。まず、 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 行目以降

繰り返しブロック内部は省略しました。

for 文

このような使い方には、 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 <=> 1001
10 <=> 100

<=>, cmp の場合は、右辺が小さければ 1、逆ならば -1、等しい時には 0 を返します。

Copyright SUGAI, Manabu. Since: 1st/Jun./2001
FC2> モビット