ループ内の処理をもう一度開始する
redo
コマンドは、条件を再評価せずにループブロックを再び開始します。
もし continue
ブロックがあれば、それは実行されません。
LABEL が省略されると、このコマンドは最も内側のループを参照します。
my $count = 0;
LINE: while (<STDIN>) {
$count++;
if ( $count % 2 ) {
redo LINE;
}
print $count, "\n";
}
redo EXPR
という書き方は Perl 5.18.0 から使えるようになりましたが、
これによって実行時にラベル名を算出することができるようになりました。
それ以外は redo LABEL
と同等です。
my $labelname = 'LINE';
my $count = 0;
LINE: while (<STDIN>) {
$count++;
if ( $count % 2 ) {
redo $labelname;
}
print $count, "\n";
}
redo
は、eval {}
, sub {}
, do {}
などのように、一般的に値を返すようなブロックから値を返すことはできません。
redo
はフロー制御の振る舞いを実行し、一切の戻り値を除外します。
そのため、grep
や map
の処理を抜け出すために redo
を使ってはいけません。
なお、ブロックは意味的には一度だけ実行されるループと同義と捉えることも可能です。
そのため、そのようなブロックの中にある redo
は効率的にそのブロックをループ構成に変えます。
前述の通り、値を返さないブロックであれば、ループでなくても redo
は使えます。
次の例はランダムに 0 から 99 までの整数を生成します。 そしてその値が 10 の倍数でなければ、ブロックの先頭に戻ります。 10 の倍数なら、それを出力してブロックを抜けます。
{
my $num = int( rand(100) ); # 0 から 99 までの整数
redo if $num % 10; # $num が 10 の倍数でなければブロックの先頭に戻る
print "${num}\n";
}