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 OKLooking through the source,
Perl_newWHILEOPinop.cspecifically has tests forreaddir,glob,readlineandeach... Hmm, let's do some digging, and see whenreaddirwas added.A bit of digging with
gitreveals that it's been that way since at least 1998, with Gurusamy Sarathy making the relevant change in commit55d729e4. 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
Chas. Owens : Interesting, glob in while does get tested for definedness, but bsd_glob in while does not. Looks like it is time for a document patch.Alnitak : see also the counter example in my question, where you can fool Perl's DWIM logic if the call to readdir() is not directly in the while() loop but in a function called in the while() test. -
perldoc perlop explains the implicit defined test in the while loop for in the context of readline.
Chas. Owens : Yeah, but it says nothing about readdir or glob.Sinan Ünür : I know. However, knowing that both readdir and glob return undef when there is nothing left to return in scalar context and considering that the same DWIMery that enables while ( <$in> ) to do the right thing in that context would come in handy here as well might be helpful.Chas. Owens : Which is why that link was part of the original question. I even quoted from it. The issue isn't what is it doing, it is where is it documented. So no one can find documentation (apart from the code) that says this behavior exists or will continue to exist.
0 comments:
Post a Comment