2009-05-09 3 views
6

Siehe auch: Where in the documentation does it say that while tests readdir for definedness?. (kein Duplikat, nur eng verwandten.)Wie ist "0" Ergebnis von readdir() nicht falsch in einer Weile?


Viele Menschen behandeln die Schleife unten als idiomatische:

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

statt:

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

weil angeblich mit dem letzteren Version Wenn der Dateiname nur "0" (Null) ist, sollte er die Schleife beenden, während er 'undef' zurückgibt, wenn keine weiteren Dateien vorhanden sind.

Aber irgendwann in der Vergangenheit dieser Test für defined() aufgehört zu werden notwendig - es scheint, spezielle Fall-Code, der die letztere Version funktioniert unabhängig zu ermöglichen.

Ich würde gerne wissen, wie das funktioniert?

Seltsamerweise, wenn ich den Anruf zu readdir() mit einem Aufruf an foo() statt ersetzen:

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

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

dann dem Code nicht tun, was würde ich erwarten, und beendet die Schleife, wenn eine Datei mit dem Namen „0 " gefunden.

(mit Perl getestet 5.8.9 auf MacOS X 10.5.6)

Antwort

11

Es ist Magie. Insbesondere während der Magie (dokumentiert in perlsyn, perlop, und wahrscheinlich an anderen Orten, an die ich mich nicht erinnern kann). Perl erlaubt Ihnen bestimmte Kurzbezeichnungen. Wenn Sie sehen möchten, was Perl hinter Ihrem Rücken macht, können Sie B::Deparse verwenden. Hier ist eine Datei, die Kurz Schleife verwendet:

#!/usr/bin/perl 

use strict; 
use warnings; 

opendir my $dir, "/tmp" or die "$!"; 

while (my $file = readdir($dir)) { 
    print "$file\n"; 
} 

Wenn Sie perl -MO=Deparse filename.pl führen Sie den Code erhalten Perl sieht:

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 
+3

+1 für B :: Deparse - wäre wirklich hilfreich, wenn jemand zur Verfügung stellen kann Links zu spezifischer Dokumentation. Ich kann es nicht in Mann perlsyn finden. – Alnitak

+0

Klicken Sie auf B :: Verteilen Sie die Dokumentation, klicken Sie auf perlsyn, um zu dem Abschnitt von perlsyn zu gelangen, der das Verhalten dokumentiert (suchen Sie nach "was Perl für die explizit geschriebene Version ist:"). Irgendwo gibt es bessere Dokumente, aber ich kann mich nicht erinnern, wo. –

+0

Es wurde ein Link zum Perlop-Abschnitt hinzugefügt, der dies ebenfalls abdeckt, aber immer noch keine speziellen Dokumente darüber, warum readdir die gleiche Behandlung erhält. –