Как результат "0" из readdir() не ложен в состоянии while?
См. Также: Где в документации говорится, что во время тестирования 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".
(протестировано с Perl 5.8.9 на MacOS X 10.5.6)
1 ответ
Это волшебство Конкретно пока магия (задокументировано в 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