46 votes

Qu'est-ce que _ (trait de soulignement simple) dans Perl sans $ ou @?

J'ai un code comme celui-ci:

 if (!-d _ || !-o _ || ($vncUserDirUnderTmp && ($mode & 0777) != 0700)) {
    raise Exception("$prog: Wrong type or access mode of $vncUserDir.\n")
}
 

Je pourrais trouver des informations sur @_ et $_ en Perl mais pas sur _ . Qu'est-ce que cela signifie en -d _ et -o _ ici?

58voto

zdim Points 29788

Lorsqu'il est utilisé avec un filetest (-X) de l'opérateur de l' stat structure du fichier précédent test est utilisé

Si l'un des fichiers les tests (ou le stat ou lstat opérateur) est donné le descripteur de fichier spécial composé d'un solitaire souligner, puis l' stat structure du fichier précédent test (ou stat opérateur) est utilisé, l'enregistrement d'un appel système.
...
Exemple:

stat($filename);  
print "Readable\n" if -r _;  
print "Writable\n" if -w _;
...

Donc dans votre exemple, !-d _ teste si le fichier dernier stat-ed n'est pas un répertoire.

Mise à jour

L'insolite _ est vraiment un typeglob *_ mais avec les opérateurs attendent à un descripteur de fichier pour l' * peut être omis, comme <*STDIN> peut être écrite comme <STDIN>. Il est trouvé dans la table des symboles

print *{$main::{_}}{IO}, "\n";   # -->  IO::Handle=IO(0x2311970)

Dans un one-liner l' *_ monte seulement après des appels à l' stat et _ sont réalisés.

40voto

Dave Cross Points 17363

Lorsque vous appelez le fichier de test opérateurs (-f, -d, -s, etc) Perl fait réellement un appel au système d'exploitation de l' stat fonction. L' stat fonction renvoie une structure pleine de toutes sortes d'informations intéressantes sur le fichier en question, mais chaque fichier de test opérateurs ne regarde que l'un des champs de cette structure (c'est un fichier? est-il un répertoire? c'est quoi les dimensions?)

Il est commun que vous pourriez vouloir en savoir plus qu'un morceau de l'information sur un fichier (c'est un fichier? puis-je le lire? puis-je exécuter?) Le naïf façon d'écrire qui est:

if (-f $file and -r $file and -x $file)

Mais cela fait trois appels d' stat - avec chacun d'eux ne cherche à l'un des champs de la structure. Pour atténuer la situation, Perl est intelligent et met en cache les résultats de l'appel le plus récent à l' stat. Il est mis en cache à l'encontre de la spéciale filehandle _. Donc, d'une façon plus efficace d'écrire le même code est:

if (-f $file and -r _ and -x _)

Cela ne fait qu'un appel à l' stat.

Depuis Perl 5.10, vous pouvez également utiliser "empilées fichier tests" et écrivez ce code:

if (-x -r -f $file) # Note reversed order of operators

Mise à jour: perldoc dit cela à propos de la empilés fichier opérateurs.

Comme de Perl 5.10.0, comme une forme purement syntaxique de sucre, vous pouvez pile fichier de test opérateurs, de façon à, -f -w -x $fileest équivalent à"-x $file && -w _ && -f _. (Ce n'est que fantaisie syntaxe: si vous utilisez la valeur de retour de l' -f $file comme argument à l'autre filetest opérateur, aucune magie qui va se passer.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X