代码之家  ›  专栏  ›  技术社区  ›  Alnitak

在while条件下,readdir()的结果“0”不是false吗?

  •  6
  • Alnitak  · 技术社区  · 17 年前

    参见: 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 回复  |  直到 15 年前
        1
  •  12
  •   Chas. Owens    17 年前

    这很神奇。特别是当魔法(记录在 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