另见:
Where in the documentation does it say that while tests readdir for definedness?.(不重复;只是密切相关.)
许多人将下面的循环视为惯用语:
while (defined(my $file = readdir($dir)) { ... }
代替:
while (my $file = readdir($dir)) { ... }
因为假设文件名只是“0”(零),所以应该使用后一版本,它应该终止循环,而当没有更多文件时它返回’undef’.
但是,在过去的某个时刻,对定义()的测试停止了必要 – 似乎有一些特殊的案例代码允许后一版本无论如何都能工作.
我想知道这是如何工作的?
奇怪的是,如果我用调用foo()替换对readdir()的调用:
sub foo { my ($dir) = @_; return readdir($dir); } while (my $file = foo($dir)) { ... }
那么代码确实做了我期望的事情,并在找到名为“0”的文件时终止循环.
(在MacOS X 10.5.6上使用Perl 5.8.9进行测试)
解决方法
这很神奇.特别是魔术(记录在
perlsyn
,perlop
,可能还有其他我不记得的地方). Perl允许您使用某些简写符号.如果你想看看Perl在你背后做了什么,你可以使用
B::Deparse
.这是一个使用速记循环的文件:
#!/usr/bin/perl use strict; use warnings; opendir my $dir,"/tmp" or die "$!"; while (my $file = readdir($dir)) { print "$file\n"; }
如果您运行perl -MO = Deparse filename.pl,您将获得Perl看到的代码:
use warnings; use strict 'refs'; die "$!" unless opendir my $dir,'/tmp'; while (defined(my $file = readdir $dir)) { do { print "$file\n" }; } filename.pl Syntax OK