2009-05-10 8 views
5

Voir aussi: How is "0" result from readdir not false in a while condition?. (pas un doublon, tout étroitement lié.)Où dans la documentation est-il dit que pendant que les tests readdir pour la définition?


Où dans la documentation-t-il dire que si les tests READDIR pour définition des modèles? Par exemple, ce code

#!/usr/bin/perl 

use strict; 
use warnings; 

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

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

lorsqu'il est exécuté par B::Deparse rendements:

use warnings; 
use strict 'refs'; 
die "$!" unless opendir my $dir, '/tmp'; 
while (defined(my $file = readdir $dir)) { 
    do { 
     print "$file\n" 
    }; 
} 
z.pl syntax OK 

je me attends à ce comportement, mais je ne peux pas trouver où il est spécifié. Dans le I/O Operators section of perlop il dit

Les lignes suivantes sont équivalentes:

        while (defined($_ = <STDIN>)) { print; }
        while ($_ = <STDIN>) { print; }
        while (<STDIN>) { print; }
        for (;<STDIN>;) { print; }
        print while defined($_ = <STDIN>);
        print while ($_ = <STDIN>);
        print while <STDIN>;

Mais il n'y a aucune mention de readdir.

+0

Il y avait une question plus tôt aujourd'hui étroitement liée - poser des questions sur la raison pour laquelle la boucle ne s'arrête pas sur un fichier appelé ' 0 'et fonctionnant sur MacOS X - était-ce vous? Une découverte intéressante - elle n'est probablement pas documentée, sauf sous le titre de DWIM générale de Perl. –

+0

@Jonathan Leffler J'ai répondu à cette question, mais je ne suis pas satisfait de ma réponse, alors j'ai posé une question plus directe dans l'espoir que cela puisse faire bouger la mémoire de quelqu'un. Je pourrais jurer que je l'ai vu dans les docs quelque part, mais il peut avoir été dans la programmation Perl ou un autre livre. Ou je pourrais juste l'imaginer. Si personne ne peut le trouver dans les documents, je vais probablement soumettre un correctif en l'ajoutant à la partie de perlfunc de readdir. Je n'aime pas me fier à un comportement non documenté. –

+0

BTW, cela est venu parce que j'ai remarqué une charge complète d'échantillons dans "Higher Order Perl" qui n'avait pas le test défini(). J'ai posté l'auteur en disant "c'est faux". Il a renvoyé en disant "non ce n'est pas". – Alnitak

Répondre

6

Vous avez raison de dire que ce n'est pas documenté. J'ai regardé plutôt dur, et je ne trouve aucune référence à ce que ce soit spécial non plus. Il est spécial, que vous avez découvert, et comme le démontre:

$ perl -MO=Deparse \ 
     -E'opendir(my $dir, "."); while($_ = readdir($dir)) { say; }' 

BEGIN { 
    $^H{'feature_say'} = q(1); 
    $^H{'feature_state'} = q(1); 
    $^H{'feature_switch'} = q(1); 
} 
opendir my $dir, '.'; 
while (defined($_ = readdir $dir)) { 
    say $_; 
} 
-e syntax OK 

En regardant à travers la source, Perl_newWHILEOP dans op.c a spécifiquement des tests pour readdir, glob, readline et each ... Hmm, faisons creuser, et voir quand readdir a été ajouté.

Un peu de creuser avec git révèle que c'est ainsi depuis au moins 1998, avec Gurusamy Sarathy apportant la modification pertinente dans la validation 55d729e4. Bien que je ne sois pas allé voir ce qui s'est passé, je parierais que ce serait au moins 5.6.0. Je ne trouve aucune mention de cela dans les deltas.

pourrait être être mentionné dans la troisième édition camel book, mais je n'ai pas vérifié pour le savoir.

Je pense qu'un patch ici (ou même juste une note à p5p) serait certainement apprécié.

Paul

+0

Intéressant, glob dans while est testé pour la définition, mais bsd_glob dans while ne le fait pas. On dirait qu'il est temps pour un patch de document. –

+0

voir aussi l'exemple de compteur dans ma question, où vous pouvez tromper la logique DWIM de Perl si l'appel à readdir() n'est pas directement dans la boucle while() mais dans une fonction appelée dans le test while(). – Alnitak

+0

En fait, la vérification de ['readdir'] (http://perldoc.perl.org/functions/readdir.html) était seulement [ajoutée en 2009 à 5.12 avec commit 114c60ecb1f775ef1deb4fdc8fb8e3a6f343d13d] (http://perl5.git.perl.org /perl.git/commit/114c60ecb1f775ef1deb4fdc8fb8e3a6f343d13d). Il a été étendu à ['each'] (http://perldoc.perl.org/functions/each.html) [en 2012 à 5.18 avec commit 8ae39f603f0f5778c160e18e08df60affbd5a620] (http://perl5.git.perl.org/perl. git/commit/8ae39f603f0f5778c160e18e08df60affbd5a620). –

2

Je suis désolé que je ne pensais pas mettre à jour les pages que vous vous attendiez à trouver cette information.

J'ai ajouté une note à la section readdir de perlfunc.

À partir de Perl 5.12, vous pouvez utiliser un readdir nu dans une boucle while, qui mis $_ à chaque itération.

opendir(my $dh, $some_dir) || die; 
while(readdir $dh) { 
    print "$some_dir/$_\n"; 
} 
closedir $dh; 

Il ne dit pas explicitement qu'il vérifie si définition des modèles.

(Je voudrais noter que l'ajout de cette fonctionnalité a été mon premier patch pour le noyau Perl.)