第46回 forとwhileの違い その1

今回は、forとwhileの違いについて。


forで配列をひとつずつ処理する方法は、なんども見てきましたが、whileの例はさほどだしていません。

では、次のように書いてみるとどうでしょうか?

use strict;

my @c = ('a', 'b', 'xxx', 'yyy', 'zzz');

# for と間違えてないかい 
while(@c){ 
  print $_, "\n";
}

結果:





(以下無限ループ)

このように無限ループになってしまいます。
あるときの例外を除いて、whileはforのように$_に値をいれません。
ですから、$_に何も入っていないので、なにも表示されず、ただ改行され無限ループになるのです。

ブール値コンテキスト

第19回 文字列の話をしよう コンテキストをふまえて - bingo_nakanishiの他言語出身者のためのPerl入門
ここで、スカラーコンテキストが3つあることを話ましたが、
whileの( ) の中はスカラーコンテキストなのです。
そして、whileは条件が満たす間ループするわけですから、ブール値コンテキストでもあります。

Perlが真と判断するものについては、
Perlにおける真偽値 - Perl入門ゼミ
こちらに詳しいことが書かれています。


配列をスカラーコンテキストで評価すると、配列の大きさが返ってきましたね。
(参考:2008-10-12

ですから、whileは、次のように評価しているわけです。

while(5){}

なわけです。5は、真ですから、無限ループしてしまいます。
では、なんとかして配列の大きさを0にすれば

while(0){}

となって、偽となり、ループを終えることができます。


以下のようにしてみましょう。

use strict;

my @c = ('a', 'b', 'xxx', 'yyy', 'zzz');

# whileの中で @c を shiftしている 
while(@c){ 
  my $d = shift @c;
  print $d, "\n";
}

結果:

a
b
xxx
yyy
zzz

このように ループを終えることができました。



今回は、whileの( )の条件の中は、スカラーコンテキストであるということを示すためにこのようなソースを書きましたので、純粋に配列を回すときは、forを使ってくださいね。


それでは、また〜