Location : Home > Languages > Perl > Instruction
Title : Control Structure
Toolbox Logo

Control Structure

 Perl は…というか、たいていのインタプリタはそうなんだろうけど…プログラムに記述されている順に解釈・実行される。しかし時には実行時における条件によってあるコマンドを飛ばしたり、繰り返したりしたい場合がある。これを記述するのが制御構造である。

if / unless

 ある条件を満たすか否かで実行するコマンド群を切り替えるために用いられる。


if ( expression1 ){
   ture1_statemant1;
   ture1_statemant2;
} elsif ( expression2 ) {
   true2_statemant1;
   true2_statemant2;
} else {
   false_statemant1;
   false_statemant2;
}

 上のような構文では、expression1 が真であれば最初のブロックが実行され、expression1 は偽だけれども expression2 が真であれば2つめのブロックが実行され、どちらも偽であれば最後のブロックが実行される。elsif 文はいくつあってもよい。逆にこの全てがそろっている必要はなくて、


if ( expression1 ){
   ture1_statemant1;
   ture1_statemant2;
}

という形式でもよい。またこの if 文が「〜が真ならば○○を実行せよ」という形式であるのに対し、「〜が偽ならば○○を実行せよ」と記述したい場合がある。この場合は if の代わりに unless を用いることができる。

for

 ある条件を満たすか否かでコマンド群を繰り返し実行するための構文として for 文がある。


for ( initial; check; increment ){
   statemant1;
   statemant2;
}

 上のような構文では、まず initial が評価される。ここではループの初期値が設定される。初期値を設定する必要がないのなら空でもよい。次に check 部分に記述された式を評価し、これが真なら以下のブロックが実行される。その後 increment 部分に記述されたないように従って後処理を行う。よく使われるのは、ループを繰り返した回数をインクリメントしておき、指定された回数になればループから出るというものである。例えば、「1から10までを足す」という処理は以下のように記述される。


$sum = 0;
for ($i = 1; $i <= 10; $i++){
   $sum = $sum + $i;
}
print $sum;

foreach

 for 文は、配列などで要素に添字が与えられている場合にその処理を記述する際には極めて有効であるが、Perl で扱う変数には必ずしも数値でインデクスが与えられていないものも多い。特にあるリストに対し、その全要素について同一の処理を行うには for では記述が面倒である。そのような場合にこの foreach が有効である。


foreach $i ( @list ){
   statemant1;
   statemant2;
}

 上のような構文では、@list に格納されている全要素について、以下のブロックで記述されているコマンドを実行する。


@a = (1,2,3,4,5);
foreach $i ( @a ){
   print $i;
}

 上のような構文では、@list に格納されている全要素について順序を入れ替えて出力するのだから、結果は 54321 である。

while / until

 for/foreach 文では、繰り返す対象の個数(言い換えれば繰り返し回数)が例えば「1から10まで」とか「配列の全要素」などと言う具合にあらかじめわかっていることが多い。ところが実際の局面では、ひたすら入力されるデータを処理し続け、データが来なくなったら終了ということも少なくない。そのような場合、for / foreach で記述しにくい場合が多い。そのような際に while / until を用いる。


while ( expression ){
   statemant1;
   statemant2;
}

 上のような構文では、expression が真である限り、以下のブロックで記述されているコマンドを繰り返し実行し続ける。もしブロック内の記述が不用意であればループからできることができなくて無限ループとなってしまうことがあるので要注意である。また if に対する unless のように「〜が偽ならば○○を実行せよ」と記述したい場合がある。この場合は while の代わりに until を用いることができる。

last 演算子

 これまでの制御文法だけでは、ループの途中から外へ抜け出すという処理を簡単に記述できない。これを補うのがこれから述べる3つの演算子である。まず last 演算子は、それを囲む最も内側のループから抜け出し、そのブロックの直後から実行する。


while ( Expression1 ){
   Statemant1;
   if ( subExpression1 ){
      SubStatement1;
      last; # ここでループを抜け出す
   }
   Statement2;
}
# last によってここに来る

next 演算子

 last 演算子がループの外に出るのに対し、ループ内で以降の処理をスキップし次の処理に移行する演算子 next が準備されている。


while ( Expression1 ){
   Statemant1;
   if ( subExpression1 ){
      SubStatement1;
      next;
   }
   Statement2;
# next によってここに来る
}

redo 演算子

 next 演算子とは逆に、ループ内の最初の処理に戻る演算子 redo が準備されている。この処理は下手に記述すると無限ループに陥ることになるので注意すること。


while ( Expression1 ){
# redo によってここに来る
   Statemant1;
   if ( subExpression1 ){
      SubStatement1;
      redo;
   }
   Statement2;
}

ラベル付きブロック

 last / next / redo 演算子ではループ内での移動やループ1つ外への移動しか許されないが、実際の処理では、ネスとされたループそのものから外へ出たい場合もある。このような場合にはラベルをつけてlast / next / redo 演算子と組み合わせて用いるとよい。ラベルを付けるには予約語を除き基本的には何でもよいが、目立つように大文字で記述することが推奨されている。


OUTERLOOP: for ($i = 1; $i <= 10; $i++){
   INNERLOOP: for ($j = 1; $j <= 10; $j++){
      if ( condition1 ) {
         statement1;
         last OUTERLOOP;
      }
      if ( condition2 ) {
         next OUTERLOOP;
      }
   }
}

 last OUTERLOOP に達した場合にはそれ以上ループ内の処理は不要で一気に外側のループの外に出る。これに対し next OUTERLOOP に達した場合は外側のループの最初に戻って処理を行う。

Toolbox Logo
Updated : 2007/03/14