Quelles sont les raisons de préférer glob sur readdir (ou vice-versa) en Perl?
Cette question est un spin-off de cette une. Un peu d'histoire: lorsque j'ai appris Perl, j'ai toujours utilisé glob
plutôt que opendir
+ readdir
parce que je l'ai trouvé plus facile. Puis, plus tard divers postes et des lectures suggéré que glob
était mauvais, et maintenant j'ai à peu près toujours utiliser readdir
.
Après réflexion sur cette dernière question j'ai réalisé que mes raisons pour l'un ou l'autre choix peuvent être superposés. Donc, je vais exposer le pour et le contre, et j'espère que les plus expérimentés Perl gens peuvent carillon et de clarifier. La question en un mot est il existe des raisons impérieuses de préférer glob
à readdir
ou readdir
à glob
(dans l'un ou dans tous les cas)?
glob
pour:
- Pas de fichiers de configuration utilisateur (sauf si vous demandez pour eux)
- Ordre des éléments est garanti
- Pas besoin de préfixer le nom du répertoire sur les éléments manuellement
- Meilleur nom (allez -
glob
contrereaddir
est pas un concours, si nous sommes en juger par les noms seuls) -
(À partir de ysth réponse; cf.
glob
contre 4 ci-dessous) Peut retourner inexistante noms de fichiers:@deck = glob "{A,K,Q,J,10,9,8,7,6,5,4,3,2}{\x{2660},\x{2665},\x{2666},\x{2663}}";
glob
inconvénients:
- Les anciennes versions sont tout simplement cassé (mais des "anciens" signifie avant 5.6, je crois, et franchement si vous êtes à l'aide de pré Perl 5.6, vous avez plus de problèmes)
- Appels
stat
à chaque fois (c'est à dire, inutile d'utiliser desstat
dans la plupart des cas). - Des problèmes avec les espaces dans les noms de répertoire (est-ce toujours le cas?)
-
(De brian réponse) Peut retourner les noms de fichiers qui n'existent pas:
$ perl -le 'print glob "{ab}{cd}"'
readdir
pour:
- (De brian réponse)
opendir
renvoie un descripteur de fichier que vous pouvez passer autour dans votre programme (et réutiliser), maisglob
retourne simplement une liste - (De brian réponse)
readdir
est un itérateur et fournit des fonctions derewinddir
,seekdir
,telldir
- Plus vite? (Pure supposition basée sur certaines
glob
's caractéristiques à partir de ci-dessus. Je ne suis pas vraiment inquiet à propos de ce niveau d'optimisation de toute façon, mais c'est théorique pro.) - Moins sujettes à bord de cas de bugs que
glob
? - Lit tout (dotfiles trop) par défaut (c'est aussi un con)
- Peut vous convaincre de ne pas le nom d'un fichier
0
(un con aussi - voir sa réponse) - Quelqu'un? Bueller? Bueller?
readdir
inconvénients:
- Si vous ne vous souvenez pas d'ajouter le nom de répertoire, vous sera obtenir bits lorsque vous essayez de faire filetests ou copier des éléments ou modifier des éléments ou...
- Si vous ne vous souvenez pas de
grep
la.
et..
éléments, vous sera obtenir bits lorsque vous comptez les éléments, ou d'essayer de marcher de façon récursive en bas de l'arborescence de fichiers ou de... - Ai-je mentionné les préfixant le nom du répertoire? (Une note, mais mon tout premier post du Perl Débutants de la liste de courrier était le classique, "Pourquoi est-ce code impliquant filetests fonctionne pas de temps en temps?" problème lié à cette chasse aux sorcières. Apparemment, je suis toujours amer.)
- Articles sont retournés dans aucun ordre particulier. Cela signifie que vous devrez souvent n'oubliez pas de les trier, d'une certaine manière. (Ce pourrait être un pro si cela signifie plus de vitesse, et si cela signifie que vous avez réellement pense sur la façon et si vous avez besoin de trier les éléments.) Modifier: Terrifiant petit échantillon, mais sur un Mac
readdir
renvoie les éléments dans l'ordre alphabétique, insensible à la casse. Sur un système Debian et OpenBSD serveur, la commande est tout à fait aléatoire. J'ai testé le Mac avec Apple en Perl (5.8.8) et mon propre compilé 5.10.1. Le système Debian est 5.10.0, comme c'est la machine OpenBSD. Je me demande si c'est un problème de système de fichiers, plutôt que de Perl? - Lit tout (dotfiles trop) par défaut (c'est aussi un pro)
- N'est pas forcément bien avec un fichier nommé
0
(voir les pros - voir sa réponse)
- Sur mon Mac avec Perl 5.10.1, j'ai été en mesure de créer un répertoire avec un espace et glob retourné comme faisant partie de sa liste. J'ai même fait un nom de répertoire avec un saut de ligne dans et cela a fonctionné. 🙂
Vous devez vous connecter pour publier un commentaire.
Vous avez manqué la plus importante, la plus grande différence entre eux:
glob
vous donne une liste, maisopendir
vous donne un répertoire de la poignée. Vous pouvez passer ce répertoire autour de la poignée pour laisser à d'autres objets ou à des sous-programmes de l'utiliser. Avec l'annuaire de la poignée, la sous-routine ou de l'objet n'est pas de savoir quelque chose au sujet d'où il vient, qui d'autre l'utilise, et ainsi de suite:Avec le dirhandle, vous avez une contrôlable itérateur où vous pouvez vous déplacer avec
seekdir
, mais avecglob
vous venez de passer à l'élément suivant.Comme avec tout, les coûts et les avantages n'ont de sens que lorsqu'il est appliqué à un certain contexte. Ils n'existent pas en dehors d'un usage particulier. Vous avez une excellente liste de leurs différences, mais je ne voudrais pas qualifier ces différences sans savoir ce que vous essayez de faire avec eux.
Quelques autres choses à retenir:
Vous pouvez implémenter votre propre glob avec
opendir
, mais pas l'inverse.glob utilise sa propre syntaxe générique, et c'est tout ce que vous obtenez.
glob pouvez retourner les noms de fichiers qui n'existent pas:
glob()
et lui donner une autre syntaxe générique (démontré en perldoc quelque part)?glob avantages: Peut renvoyer "les noms de fichiers" qui n'existent pas:
cp -a dirname{,.orig}
régulièrement.)mkdir -p /home/{alice,bob,charlie}/{public_html,mail,docs}
Ici est un désavantage pour
opendir
etreaddir
.Vous vous attendriez à ce code affiche le même nombre deux fois, mais ce n'est pas parce qu'il y a un fichier avec le nom de
0
. Sur mon ordinateur, il imprime251
, et188
, testé avec Perl v5.10.0 et v5.10.1Ce problème également fait en sorte que cela imprime juste un tas de lignes vides, indépendamment de l'existence du fichier
0
:Où, comme toujours, cela fonctionne très bien:
Je fixe ces questions, et envoyé dans un patch qui fait en Perl v5.11.2, de sorte que cela fonctionne correctement avec Perl v5.12.0 d'où elle sort.
Mon fix convertit ce:
dans cette:
Qui fait que cela fonctionne de la même manière que
read
a travaillé sur les fichiers. En fait c'est le même bout de code, j'ai juste ajouté un autre élément à la correspondanteif
consolidés.. Still, I'll note it in the
readdir` cons.each
.glob
le rend facile à lire tous les sous-répertoires d'un donné fixe profondeur, comme dansglob "*/*/*"
. J'ai trouvé cette pratique à plusieurs reprises.Bien, vous avez assez bien le couvrir. Tout ce que la prise en compte, j'aurais tendance à utiliser
glob
quand je suis en jetant un rapide one-off script et son comportement est exactement ce que je veux, et l'utilisationopendir
etreaddir
dans la continuité de la production de code ou de bibliothèques où je peux prendre mon temps et plus claire, plus propre code est utile.Pour les petits, des choses simples, je préfère
glob
. Juste l'autre jour, je l'ai utilisé et à une vingtaine de ligne de script perl pour modifier le balisage d'une grande partie de ma bibliothèque de musique.glob
, cependant, a un joli nom étrange. Glob? Ce n'est pas du tout intuitif, dans la mesure où le nom va.Mon plus grand raccrocher avec
readdir
est qu'il traite d'un répertoire dans un sens, c'est un peu étrange pour la plupart des gens. Généralement, les programmeurs ne pense pas que d'un répertoire sous forme d'un flux, qu'ils pensent comme d'un outil, ou une liste, qui glob fournit. Le nom est mieux, la fonctionnalité est mieux, mais l'interface laisse encore à désirer.readdir
un peu bouché (comme un nom) etglob
juste au sujet de droit. Puis de nouveau, j'aime Rubysplat
opérateur (un nom et un autre) donc je suppose que je suis bizarre.Qui a une liste assez complète.
readdir
(etreaddir
+grep
) a moins de frais généraux queglob
et ce qui est un plus pourreaddir
si vous avez besoin d'analyser des tas et des tas de répertoires.Exception:
Aussi loin que je peux dire, la règle pour
glob
est: vous devez fournir un chemin d'accès complet au répertoire afin d'obtenir le meilleur des chemins. Le Perl docs semblent ne pas mentionner que, ni l'un des postes ici.Qui signifie que
glob
peut être utilisé à la place dereaddir
quand vous voulez juste les noms de fichiers (plutôt que par des chemins), et vous ne voulez pas les fichiers cachés retourné, c'est à dire celles commençant par un '.'. Par exemple,Sur une note similaire,
File::Slurp
a une fonction appeléeread_dir
.Depuis que j'utilise
File::Slurp
's d'autres fonctions beaucoup dans mes scripts,read_dir
est également devenu une habitude.Il a également des options suivantes:
err_mode
,prefix
, etkeep_dot_dot
.Tout d'abord, faire un peu de lecture. Chapitre 9.6. de la Perl Livre De Recettes décrit le point que je veux obtenir de bien, un peu moins de la discussion tête de.
Deuxièmement, de faire une recherche pour
glob
etdosglob
dans votre répertoire Perl. Alors que de nombreuses sources différentes (les moyens d'obtenir la liste des fichiers) peuvent être utilisés, la raison pour laquelle je vousdosglob
est que si vous arrive d'être sur une plate-forme Windows (et à l'aide de ladosglob
solution), il est fait à l'aideopendir
/readdir
/closedir
. D'autres versions en utilisant les commandes du shell ou précompilés OS des exécutables spécifiques.Si vous savez que vous êtes cibler une plate-forme spécifique, vous pouvez utiliser cette information à votre avantage. Juste pour la référence, j'ai cherché dans cette sur Strawberry Perl Portable edition 5.12.2, donc les choses peuvent être légèrement différents sur les nouveaux ou originaux versions de Perl.