while (defined($line = )) と while ($line = )
%ls -l total 4 -rw-r--r-- 1 peanutsjamjam wheel 1 Jan 27 09:09 data.txt -rwxr-xr-x 1 peanutsjamjam wheel 387 Jan 27 10:07 test.pl* %cat data.txt 0%hexdump -C data.txt 00000000 30 |0| 00000001 %cat test.pl #! /usr/bin/perl print "defined あり\n"; open FILE, "<data.txt" or die; while (defined($line = <FILE>)) { print "hello\n"; } close FILE; print "defined なし\n"; open FILE, "<data.txt" or die; while ($line = <FILE>) { print "hello\n"; } close FILE; print "if の場合\n"; open FILE, "<data.txt" or die; if ($line = <FILE>) { print " true\n"; } else { print "false\n"; } close FILE; %./test.pl defined あり hello defined なし hello if の場合 false %
へんなの。
手元で man perlsyn
(あるいは perldoc perlsyn
) と打ってマニュアルを確認すると、Compound Statements のところに、こうある。
The "while" statement executes the block as long as the expression is true (does not evaluate to the null string "" or 0 or "0").
FreeBSD の ports でインストールした Perl の日本語マニュアルにも*1、同じことが書いてある。
while 文は、式が真である間 (評価結果が、空文字列、0、"0" のいずれかでない間) ブロックを実行します。
私が手元で試してみたところでは、上に示した通り、defined
を付けない場合でも while
のループの中(マニュアルで言うところのブロック)に処理が入ってしまっている。
while
の横の括弧の中に書いた条件式が「真」と判断されてしまったということなのだけど、同じ式を if
文の括弧の中に書くと、きちんと「偽」と判断される。
Google に行って「perl defined 改行」という3つの単語で検索したら、結城さんのところが上から2つめに出てきた。
- perl-lesson ML ダイジェスト
- http://www.hyuki.com/pb/pbmldig.html#i3
私も環境を明記しておこう。
環境
環境:
%uname -rps FreeBSD 6.1-RELEASE-p12 i386 %perl -v This is perl, v5.8.8 built for i386-freebsd-64int (with 1 registered patch, see perl -V for more detail) Copyright 1987-2006, Larry Wall (略)
*1:japanese/p5-manual. これはちょっと内容が古いものだけど、この部分に関してはまったく変更が要らないと思う