私は通常、次のコードを使用してファイル内の行をループします。
open my $fh, '<', $file or die "Could not open file $file for reading: $!\n";
while ( my $line = <$fh> ) {
...
}
ただし、別の質問に答える際に、Evan Carrollは私の答えを編集し、私のwhile
ステートメントを次のように変更しました。
while ( defined( my $line = <$fh> ) ) {
...
}
彼の理論的根拠は、次の行がある場合0
(最後の行である必要があり、そうでない場合はキャリッジリターンがあります)、while
私のステートメント($line
に設定され"0"
、からの戻り値)を使用すると、途中で終了するというものでした。したがって、割り当ては、"0"
falseと評価される割り当てにもなります)。定義性をチェックすれば、この問題に遭遇することはありません。それは完全に理にかなっています。
だからやってみました。最後の行に0
キャリッジリターンがないテキストファイルを作成しました。ループを実行しましたが、ループが途中で終了しませんでした。
それから私は、「ああ、多分価値は実際にはないかもしれない0
、多分そこに物事を台無しにしている何か他のものがあるかもしれない!」と思いました。だから私はDump()
から使用しました、Devel::Peek
そしてこれはそれが私に与えたものです:
SV = PV(0x635088) at 0x92f0e8
REFCNT = 1
FLAGS = (PADMY,POK,pPOK)
PV = 0X962600 "0"\0
CUR = 1
LEN = 80
明示的に設定したスカラーを"0"
呼び出すと同様の結果が得られるため、値は実際には文字列であることがわかります(唯一の違いはLENフィールドにあります-ファイルLENは80ですが、スカラーからのLENは8)です。Dump()
"0"
それで、取引は何ですか?キャリッジリターンがないwhile()
行だけをループに渡すと、ループが途中で終了しないのはなぜですか?"0"
Evanのループは実際にはより防御的ですか、それともPerlは内部で何かおかしなことをしますか?つまり、これらのことを心配する必要はなく、while()
実際にヒットしたときにのみ終了しますeof
か?