How is the result "0" from readdir () not false in the while state?

See also: Where the documentation says that during readdir testing for definition? . (Not a duplicate, just closely related.)


Many people view the cycle below as idiomatic:

while (defined(my $file = readdir($dir)) { ... } 

instead:

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

because, presumably, with the latest version, if the file name is β€œ0” (zero), it should break the loop, whereas it returns β€œundef” when there are no more files.

However, at some point in the past, this test for defined() ceased to be necessary - it seems that there is a special case code that allows the latest version to work independently.

I would like to know how it works?

Curiously, instead of calling readdir() instead of calling foo() instead of foo() replace

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

then the code will really do what I expect and end the loop when a file with the name "0" is found.

(tested with Perl 5.8.9 on MacOS X 10.5.6)

+6
perl while-loop readdir defined
source share
1 answer

This is magic. In particular, while magic (documented in perlsyn , perlop , and possibly in other places that I don’t remember). Perl allows you to make some abbreviations. If you want to see what Perl is doing behind you, you can use B::Deparse . Here is a file that uses a shorter loop:

 #!/usr/bin/perl use strict; use warnings; opendir my $dir, "/tmp" or die "$!"; while (my $file = readdir($dir)) { print "$file\n"; } 

If you run perl -MO=Deparse filename.pl , you get the Perl code that sees:

 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 
+11
source share

All Articles