readdir()的“0”结果如何在一段时间内不是假的?

时间:2009-05-09 14:42:52

标签: perl while-loop readdir defined

另见: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'。

然而,在过去的某个时刻,defined()的测试停止了必要 - 似乎有一些特殊的案例代码允许后一版本无论如何都能正常工作。

我想知道这是如何运作的?

奇怪的是,如果我通过拨打readdir()来取代对foo()的通话:

sub foo
{
    my ($dir) = @_;
    return readdir($dir);
}

while (my $file = foo($dir)) {
    ...
}

然后代码 做我期望的事情,并在找到名为“0”的文件时终止循环。

(在MacOS X 10.5.6上使用Perl 5.8.9测试)

1 个答案:

答案 0 :(得分:12)

这很神奇。特别是在魔法时(记录在perlsynperlop,以及其他我不记得的地方)。 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