我通常使用以下代码在文件中循环:
open my $fh,'<',$file or die "Could not open file $file for reading: $!\n"; while ( my $line = <$fh> ) { ... }
但是,in answering another question,Evan Carroll编辑我的答案,把我的while语句改成:
while ( defined( my $line = <$fh> ) ) { ... }
他的理由是,如果你有一行是0(它必须是最后一行,否则它会有一个回车),那么如果你使用我的语句,你的while会退出($line将被设置为“0” “,并且赋值的返回值因此也将为”0“,将其评估为false).如果你检查定义,那么你不会遇到这个问题.这是完美的.
所以我试过了我创建了一个文本文件,其最后一行为0,没有回车.我通过我的循环运行它,循环没有过早退出.
然后我想,“哈哈,也许这个价值实际上不是0,也许还有其他的东西在扭转事情!”所以我用Devel :: Peek的Dump(),这是它给了我什么:
SV = PV(0x635088) at 0x92f0e8 REFCNT = 1 FLAGS = (PADMY,POK,pPOK) PV = 0X962600 "0"\0 CUR = 1 LEN = 80
这似乎告诉我,该值实际上是字符串“0”,因为我得到一个类似的结果,如果我调用Dump()在标量我已经明确设置为“0”(唯一的区别是在LEN字段 – – 从文件LEN是80,而标量LEN是8).
那么什么交易呢?为什么我的while()循环过早退出,如果我传递一行只有“0”,没有回车? Evan的循环实际上更防守了,或者Perl在内部做一些疯狂的事情,这意味着你不需要担心这些事情,而()()实际上只有当你打eof时才退出?
解决方法
因为
while (my $line = <$fh>) { ... }
实际上是汇编到
while (defined( my $line = <$fh> ) ) { ... }
这可能是一个非常老版本的perl,但不再需要了!您可以从脚本中运行B :: Deparse看到这一点:
>perl -MO=Deparse open my $fh,$file or die "Could not open file $file for reading: $!\n"; while ( my $line = <$fh> ) { ... } ^D die "Could not open file $file for reading: $!\n" unless open my $fh,$file; while (defined(my $line = <$fh>)) { do { die 'Unimplemented' }; } - Syntax OK
所以你已经很好去了!