也可以看看: 在文档中,它在哪里说,在测试readdir的定义时?. (不是重复的;只是密切相关。)


许多人将下面的循环视为惯用性:

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测试)

有帮助吗?

解决方案

这是魔术。特别是魔术时(记录在 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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top