Как результат «0» от readdir () не ложь за некоторое время?
-
20-08-2019 - |
Вопрос
Смотрите также: Где в документации говорится, что в то время как тестирование 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)
Решение
Это магия. В частности, когда волшебство (задокументировано в 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
Вы получаете код, который видит:
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