See also: How is "0" result from readdir not false in a while condition?. (Not a duplicate; just closely related.)
Where in the documentation does it say that while tests readdir for definedness? For instance, this code
#!/usr/bin/perl
use strict;
use warnings;
opendir my $dir, "/tmp" or die "$!";
while (my $file = readdir($dir)) {
print "$file\n";
}
closedir $dir;
when run through B::Deparse yields:
use warnings;
use strict 'refs';
die "$!" unless opendir my $dir, '/tmp';
while (defined(my $file = readdir $dir)) {
do {
print "$file\n"
};
}
z.pl syntax OK
I expect this behaviour, but I cannot find where it is specified. In the I/O Operators section of perlop it says
The following lines are equivalent:
while (defined($_ = <STDIN>)) { print; }
while ($_ = <STDIN>) { print; }
while (<STDIN>) { print; }
for (;<STDIN>;) { print; }
print while defined($_ = <STDIN>);
print while ($_ = <STDIN>);
print while <STDIN>;
But there is no mention of readdir
.
You're quite right about it being undocumented. I've looked rather hard, and I can't find any reference to it being special either. It is special, as you've discovered, and as demonstrated by:
$ perl -MO=Deparse \
-E'opendir(my $dir, "."); while($_ = readdir($dir)) { say; }'
BEGIN {
$^H{'feature_say'} = q(1);
$^H{'feature_state'} = q(1);
$^H{'feature_switch'} = q(1);
}
opendir my $dir, '.';
while (defined($_ = readdir $dir)) {
say $_;
}
-e syntax OK
Looking through the source, Perl_newWHILEOP
in op.c
specifically has tests for readdir
, glob
, readline
and each
... Hmm, let's do some digging, and see when readdir
was added.
A bit of digging with git
reveals that it's been that way since at least 1998, with Gurusamy Sarathy making the relevant change in commit 55d729e4
. While I haven't gone digging to see which releases that's gone into, I'd wager it would be at least 5.6.0 and above. I can't find any mention of it in the deltas.
It might be mentioned in the third edition camel book, but I haven't checked to find out.
I think that a patch here (or even just a note to p5p) would certainly be appreciated.
Paul
I'm sorry that I didn't think to update the pages that you expected to find this information.
I did add a note to the readdir
section of perlfunc
though.
As of Perl 5.12 you can use a bare
readdir
in awhile
loop, which will set$_
on every iteration.opendir(my $dh, $some_dir) || die; while(readdir $dh) { print "$some_dir/$_\n"; } closedir $dh;
It doesn't explicitly say that it checks for definedness though.
( I would like to note that adding this feature was my first patch to the Perl core. )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With