2009-05-09 15 views
6

Vedere anche: Where in the documentation does it say that while tests readdir for definedness?. (Non un duplicato; solo strettamente legata.)Com'è risultato "0" da readdir() non falso in una condizione while?


Molte persone trattano il ciclo di seguito come idiomatica:

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

invece di:

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

perché si suppone con quest'ultimo versione se il nome del file è solo "0" (zero) dovrebbe terminare il ciclo, mentre restituisce 'undef' quando non ci sono più file.

Tuttavia, a un certo punto nel passato questo test per defined() ha smesso di essere necessario - sembra esserci un codice di caso speciale che consente a quest'ultima versione di funzionare indipendentemente.

Mi piacerebbe sapere come funziona?

Curiosamente, se sostituisco la chiamata a readdir() con una chiamata a foo() invece:

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

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

quindi il codice fa fare ciò che mi aspettavo, e terminare il ciclo quando un file chiamato "0 " è stato trovato.

(testato con Perl 5.8.9 su MacOS X 10.5.6)

risposta

11

Si tratta di magia. Nello specifico durante la magia (documentata in perlsyn, perlop, e probabilmente in altri luoghi che non ricordo). Perl ti consente alcune notazioni di stenografia. Se vuoi vedere cosa sta facendo Perl dietro la schiena, puoi usare B::Deparse. Ecco un file che utilizza il ciclo scorciatoia:

#!/usr/bin/perl 

use strict; 
use warnings; 

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

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

Se si esegue perl -MO=Deparse filename.pl si ottiene il codice Perl vede:

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 per B :: Deparse - sarebbe veramente utile se qualcuno in grado di fornire collegamenti a documentazione specifica. Non riesco a trovarlo nell'uomo perlsyn. – Alnitak

+0

Fare clic su B :: Deparse per i documenti su di esso, fare clic su perlsyn per accedere alla sezione di perlsyn che documenta il comportamento (cercare "che è Perl short-hand per la versione scritta più esplicitamente:"). Ci sono documenti migliori da qualche parte, ma non riesco a ricordare dove. –

+0

Aggiunto un collegamento alla sezione perlop che copre anche questo, ma ancora nessun documento specifico sul perché readdir ottiene lo stesso trattamento. –