2009-05-09 4 views
6

Véase también: Where in the documentation does it say that while tests readdir for definedness?. (No es un duplicado, sólo estrechamente relacionado.)¿Cómo es "0" el resultado de readdir() no falso en una condición de tiempo?


Muchas personas tratan el lazo abajo como idiomática:

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

en lugar de:

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

porque supuestamente con este último versión si el nombre de archivo es solo "0" (cero) debe terminar el ciclo, mientras que devuelve "undef" cuando no hay más archivos.

Sin embargo, en algún momento en el pasado esta prueba para defined() dejó de ser necesaria, parece haber un código de caso especial que permite que la última versión funcione independientemente.

Me gustaría saber cómo funciona esto?

Curiosamente, si se sustituye la llamada a readdir() con una llamada a foo() lugar:

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

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

luego el código qué hacen lo que cabe esperar, y terminar el bucle cuando un archivo con el nombre "0 " es encontrado.

(probado con Perl 5.8.9 en MacOS X 10.5.6)

Respuesta

11

Es magia. Específicamente mientras que la magia (documentado en perlsyn, perlop, y probablemente en otros lugares que no recuerdo). Perl te permite ciertas anotaciones de taquigrafía. Si quiere ver lo que Perl está haciendo a sus espaldas, puede usar B::Deparse. Aquí es un archivo que utiliza el bucle de forma abreviada:

#!/usr/bin/perl 

use strict; 
use warnings; 

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

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

Si ejecuta perl -MO=Deparse filename.pl te ve el código 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 
+3

+1 para B :: Deparse - sería muy útil si alguien puede proporcionar enlaces a documentación específica. No puedo encontrarlo en el hombre Perlsyn. Haga clic – Alnitak

+0

B :: Deparse de documentos en él, haga clic en perlsyn que deben adoptarse para la sección de perlsyn que documenta el comportamiento (busque "que es Perl taquigrafía para la versión más explícitamente escrito:"). Hay mejores documentos en algún lugar pero no recuerdo dónde. –

+0

agregó un enlace a la sección perlop que también cubre esto, pero todavía no hay documentos específicos sobre qué readdir recibe el mismo tratamiento. –

Cuestiones relacionadas