Problème à signaler:


Télécharger Cours et exercices avancés pour débuter en perl



★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:



Documentation Perl
version du 13 mai 2002

Avant-propos
Ce document est la traduction (encore incomplète) de la documentation originale distribuée avec perl. Ces traductions ont été réa-
lisées et relues par de nombreux volontaires. Vous pouvez retrouver l’ensemble de la documentation française Perl (éventuellement
mise à jour) en consultant, entre autres, l’URL <;.
Cette compilation en un seul document PDF a été conçue par Paul Gaborit en utilisant une version francisée du script Perl pod2latex
pour obtenir du LATEX puis converti en PDF grâce à pdflatex. Si vous utilisez la version PDF de cette documentation (ou une version
papier issue de la version PDF) pour tout autre usage qu’un usage personnel, je vous serai reconnaissant de m’en informer par un
petit message () mais rien ne vous y oblige.
Si vous avez des remarques concernant ces documents (chaque chapitre est un document spéci?que), en premier lieu, contactez
la traducteur (vous devriez trouver son adresse électronique dans la rubrique TRADUCTION) et expliquez-lui gentiment vos re-
marques ou critiques. Il devrait normalement vous répondre et prendre en compte votre avis. En l’absence de réponse, vous pouvez
éventuellement me contacter.
Vous pouvez aussi participer à l’effort de traduction de la documentaiotn Perl. Certaines parties ne sont toujours par traduites.
D’autres n’ont pas encore été relues. La plupart ne sont pas à jour par rapport à leur version anglaise originale (la version de
référence est indiquée dans chaque chapitre). Certains outils n’ont pas encore été francisés. Toutes les bonnes volontés sont donc les
bienvenues. Vous devriez trouver tous les renseignements nécessaires en consultant l’URL ci-dessus.
Le 13 mai 2002 – Paul Gaborit
Ce document PDF est distribué selon les termes de la license Artistique de Perl. Toute autre distribution de ce ?chier ou de ses
dérivés impose qu’un arrangement soit fait avec le(s) propriétaire(s) des droits. Ces droits appartiennent aux auteurs des différents
documents originaux (lorsqu’ils sont identi?és dans la rubrique AUTEUR), aux traducteurs et relecteurs pour la version française
et à moi-même pour la compilation PDF de ces documents.

1

Chapitre 1
perl – Language pratique d’extraction et de
rapport (Practical Extraction and Report
Language)

Language pratique d’extraction et de rapport (Practical Extraction and Report Language)
1.1
SYNOPSIS
perl -sTuU ] [ -hv ] [ -V[:con?gvar] ] [ -cw ] [ -d[:debugger] ] [ -D[number/list] ] [ -pna ] [ -Fpattern ] [ -l[octal] ] [ -0[octal] ] [ -Idir ] [ -
m
[-]module ] [ -M[-]’module ’ ] [ -P ] [ -S ] [ -x[dir] ] [ -i[extension] ] [ -e ’command’ ] [ – ] [ program?le ] [ argument ]
Pour en simpli?er l’accès, le manuel Perl a été scindé en plusieurs sections :
perl
Vue d’ensemble (cette section)
perldelta
Changements par rapport à la version précédente
perlfaq
Les questions souvent posées (Foire Aux Questions)
perltoc
Table des matières de la documentation Perl
perldata
Structures de données
perlsyn
Syntaxe
perlop
Opérateurs et précédence
perlre
Expressions régulières
perlrun
Invocation de Perl et ses arguments
perlfunc
Fonctions prédéfinies de Perl
perlvar
Variables prédéfinies en Perl
perlsub
Utilisation des sous-programmes
perlmod
Modules Perl : comment ça marche
perlmodlib
Modules Perl : comment en créer et les utiliser
perlmodinstall Modules Perl : comment les installer à partir du CPAN
perlform
Utilisation des formats
perllocale
Support des définitions locales
perlref
Références en Perl
perldsc
Introduction aux structures de données en Perl
perllol
Structures de données en Perl : listes de listes
perltoot
Programmation orientée objet en Perl : apprentissage
perlobj
Objets en Perl
perltie
Objets cachés derrière de simples variables
perlbot
Programmation orientée objet: astuces et exemples
perlipc
Communication interprocessus
perldebug
Debugger en Perl
perldiag
Messages de diagnostique de Perl
perlsec
Perl et la sécurité
2

1.2. DESCRIPTION
perl
perltrap
Pièges de Perl pour les imprudents
perlport
Guide de portabilité Perl
perlstyle
Guide de style Perl
perlpod
Format des documentations Perl
perlbook
Livres parlant de Perl
perlembed
Utiliser Perl dans vos programmes en C ou C++
perlapio
Interface d’abstraction des E/S internes à Perl
perlxs
Interface de programmation des extensions à Perl
perlxstut
Perl XS : Apprentissage
perlguts
Fonctions internes pour les créateurs d’extensions
perlcall
Convention de nommage des fonctions Perl en C
perlhist
Le glorieux passé de Perl
(Si vous essayez de lire l’ensemble des sections d’une traite, l’ordre indiqué tendra à réduire le nombre de référence en avant.)
Par défaut, toutes les sections citées précédement sont installées dans le répertoire /usr/local/man/fr/.
De la documentation supplémentaire sur les modules Perl est disponible. Par défaut, elle est installée dans le répertoire
/usr/local/lib/perl5/man ou dans le sous-répertoire man du répertoire de librairie Perl. Certains de ces documents supplémentaires
sont livrés en standard avec Perl, mais vous y trouverez aussi la documentation des modules provenant d’autres sources.
Vous devez être en mesure de lire la documentation perl avec la commande man(1) en ajoutant le répertoire man dans le ?chier de
démarrage adéquat, ou en modi?ant la variable d’environnement MANPATH. Pour savoir où sont installées les pages de manuel,
tapez :
perl 
Si les répertoires ont un ancêtre commun, par exemple /usr/local/man/man1 et /usr/local/man/man3, il suf?t de rajouter cet ancêtre
(/usr/local/man) dans le ?chier de con?guration de man(1) ou dans la variable MANPATH. Si ce n’est pas le cas, vous devrez alors
tous les rajouter.
Si ça ne marche pas pour une raison quelconque, vous pouvez toujours utiliser le script perldoc fourni pour lire les documentations
des modules. Vous pourriez aussi chercher un programme de remplacement à man(1).
Si votre programme a un comportement étrange et que vous ne savez pas où se trouve le problème alors demander à Perl de vous
aider, utiliser l’option -w. Très souvent Perl vous indiquera l’endroit exact où se trouve le problème.
1.2
DESCRIPTION
Perl est un langage optimisé pour extraire des informations de ?chiers textes et imprimer des rapports basés sur ces informations.
C’est aussi un bon langage pour de nombreuses taches d’administration système. Il est écrit dans le but d’être pratique (simple à
utiliser, ef?cace, complet) plutôt que beau (petit, élégant, minimaliste).
Le Perl combine (du point de vue de l’auteur) les meilleures fonctionnalités de Csedawk et sh, de telle manière que les personnes
familiarisées à ces langages ne devraient avoir aucune dif?culté avec celui-ci. (Les historiens pourront noter quelques vestiges de
cshPascal, et même de BASIC-PLUS). La syntaxe se rapproche presque totalement de celle du C. Contrairement à la plupart
des utilitaires Unix, Perl ne limite pas arbitrairement la taille des données – si vous avez assez de mémoire, Perl peut remplir une
chaine de caractères avec le contenu total d’un ?chier. Il n’y a pas de niveau maximum à la récursivité. Et les tables utilisées par
les tableaux de hachage (anciennement appellé "tableaux associatifs") croissent dès que nécessaire a?n de garantir un bon niveau
de performance. Perl utilise des techniques sophistiquées de recherche de motif pour pouvoir traiter très rapidement de très grandes
quantités de données. Bien qu’optimisé pour le traitement des ?chiers textes, Perl peut aussi traiter des données binaires, et faire
que des ?chiers dbm soit vus commes des tableaux de hachage. Les scripts Perl ayant leurs setuid bits positionnés sont plus sûrs
que des programmes C grâce à des mécanismes de suivi de ?ot de données qui permettent d’éviter de nombreux trous de securités
particulièrement stupides.
Si vous avez un problème pour lequel vous auriez utilisé sedawk ou sh, mais qui depasse leurs capacités ou qui doit fonctionner
un peu plus rapidement et que vous ne voulez pas l’écrire en C, alors le Perl est pour vous. Il existe aussi des convertisseurs pouvant
transformer vos scripts sed et awk en scripts Perl.
Mais il y a beaucoup plus
La version 5 de Perl constitue une réécriture presque complète, et introduit les fonctionnalités suivantes :
3

1.2. DESCRIPTION
perl
– De nombreuses améliorations à l’utilisation
Il est maintenant possible d’écrire du code Perl nettement plus lisible (même dans les expressions régulières). Les variables
absconses peuvent être remplacées par des identi?cateurs plus compréhensibles. Les messages d’erreurs sont plus detaillés, et les
messages optionnels d’avertissements devraient indiquer une grande majorité des erreurs peuvant être commises par un novice. On
ne le dira jamais assez, mais lorsque vous obtenez un comportement erratique, essayez de lancer votre script avec le modi?cateur
-w !!! De toutes manières, même si n’avez pas de comportement erratique, essayez d’utiliser le modi?cateur -w.
– Une grammaire simpli?ée
La taille de la nouvelle grammaire yacc fait environ la moitié de la précédente. Un très grand nombre de règles arbitraires ont
été régularisées. Le nombre des mots réservés a été réduit de plus de 2/3. Malgré celà, presque tous les anciens scripts Perl
fonctionnent sans aucun changement.
– Portée lexicale
Les variables Perl peuvent maintenant être déclarées à l’interieur d’une portée lexicale, de la même manière que les variables
"auto" en C. Non seulement, c’est plus ef?cace, mais çà contribue à une plus grande sécurité pour la programmation de code
réutilisable. Les routines anonymes disposent ainsi d’un couplage fort des variables locales.
– Structure de données performantes
N’importe quelle variable scalaire, y compris un élément de tableau, peut maintenant contenir une référence vers une autre variable
ou une routine. Il devient simple de créer des variables et routines anonymes. Perl gère pour vous les compteurs de référence.
– Modularité et réutilisabilité
La bibliothèque Perl est maintenant constituée de modules qui peuvent être partagés facilement entre plusieurs paquetages. Un
paquetage peut choisir d’importer tout ou parties de l’interface publiée d’un module. Les pragmas (directives de compilation) sont
dé?nis et utilisés par le même mécanisme.
– Programmation orientée objet
Un paquetage peut fonctionner comme un classe. L’héritage multiple dynamique et les méthodes virtuelles sont supportées de
manière très directe et n’introduisent que peu de changement syntaxiques. Les descripteurs de ?chier sont maintenant gérés
comme des objets.
– Intégrable et extensible
Perl peut maintenant être intégré simplement dans vos applications en C ou C++, et peut indifférement appeler ou être appelé par
vos routines à travers une interface documentée. Le préprocesseur XS fourni facilite l’intégration de routines en C ou C++ dans
une application Perl. Le chargement dynamique de module est supporté, et Perl lui-même peut être transformé en une librairie
dynamique.
– Conforme POSIX
Un apport majeur est la création du module POSIX, qui fournit l’accès à toutes les routines et dé?nitions POSIX, au travers de
classes d’objets lorsque c’est approprié.
– Constructeurs et destructeurs de paquetage
Les nouveaux blocs BEGIN et END sont exécutés lorsque la compilation du paquetage s’achève et juste à la sortie du programme.
Ils peuvent être utilisés dans un mode dégradé correspondant à celui du awk en utilisant les modi?cateurs -p ou -n.
– De multiples implémentations de DBM en simultané
Un script Perl peut maintenant accèder à des ?chiers DBM, NDBM, SDBM, GDBM et Berkeley DB simultanément. En fait,
l’ancienne interface dbmopen a été généralisée pour permettre à n’importe quelle variable d’être rattachée à une classe d’objet
dé?nissant ses propres méthodes d’accès.
– Les dé?nitions des routines peuvent desormais être chargées automatiquement
En fait, le mécanisme AUTOLOAD vous permet aussi de dé?nir n’importe quelle sémantique arbitraire pour l’appel de routines
indé?nies. Ce n’est pas seulement du chargement automatique.
– Amélioration des expressions régulières
Vous pouvez maintenant spéci?er des quanti?cateurs qui ne soit pas avides. Il est aussi possible de faire des regroupements sans
créer de références. Tout comme vous pouvez ajouter des espacements et des commentaires dans les expressions régulières. Un
mécanisme conséquent permettant d’étendre les capacités des expressions régulières a été ajouté mais reste presque entièrement
compatible.
– Une pléthore de modules disponibles
Le CPAN (Comprehensive Perl Archive Network ou Réseau d’archives détaillées de Perl) décrit dans la page de manuel le manuel
perlmodlib contient des centaines de modules prêts à l’emploi fournissant une quantité astronomique de code réutilisable. Vous
trouverez le site miroir le plus proche de chez vous à l’adresse : .
– Compilateur
Bien qu’il ne soit pas encore en production, il existe un compilateur Perl-vers-C qui fonctionne. Il peut générer un byte code (code
objet) portable, du simple C ou bien du code C optimisé.
D’accord, j’en ?ni avec le battage publicitaire de Perl.
4

1.3. ENVIRONMENT
perl
1.3
ENVIRONMENT
Voir le manuel perlrun.
1.4
AUTHOR
Larry Wall <>, aidé par des tas d’autres personnes.
Si vous désirez faire partager votre témoignage sur les succès remportés en utilisant Perl, aidant ainsi ceux qui voudraient recomman-
der le Perl pour leurs applications, ou tout simplement si vous voulez exprimer votre gratitude à Larry et l’équipe de développement,
alors écrivez s’il vous plait à <>.
1.5
FILES
"/tmp/perl-e$$" fichier temporaire pour les commandes -e
"@INC"
emplacements des librairies Perl
1.6
SEE ALSO
a2p
traducteur awk vers perl
s2p
traducteur sed vers perl
1.7
DIAGNOSTICS
Le modi?cateur -w génère de magni?ques diagnostiques.
Voir le manuel perldiag pour l’explication de tous ces diagnostiques. Le pragma use diagnostics oblige Perl à rendre ces messages
plus verbeux.
En cas d’erreur de compilation le numéro de la ligne fautive est indiqué ainsi que l’emplacement approximatif du mot concerné.
(Dans le cas de script utilisant le modi?cateur -e, chaque -e est compté comme une ligne.)
Les scripts en setuid ont des contraintes supplémentaires pouvant produire des messages d’erreur tel que "Insecure dependency".
Voir le manuel perlsec.
Avons-nous mentionné que vous devriez vraiment penser à utiliser le modi?cateur -w?
1.8
BUGS
Le modi?cateur -w n’est pas obligatoire.
Perl est à la merci de la dé?nition de plusieurs opérations telles que casting, atof(), et af?chage des nombres ?ottants par sprintf()
qui peuvent être différentes sur votre machine.
Si votre stdio nécessite un déplacement(seek) ou une ?n de ?chier(eof) entre les lectures et les écritures sur des ?ots de données
particuliers, alors Perl les requièrent aussi. (Ceci ne s’applique pas à sysread() et syswrite().)
Il n’y a aucune limite en ce qui concerne la taille des types de données prédé?nies (à part la mémoire disponible) mais il existe
toujours un petit nombre de limites arbitraires : un nom de variable ne peut dépasser 255 caractères, aucun composant de votre PATH
ne doit être plus long que 255 caractères si vous utiliser le modi?cateur -S. Une expression régulière ne peut dépasser 32767 octets
lors de sa compilation.
Si vous envoyez un rapport de bug (assurez-vous d’inclure toutes les informations sur la con?guration obtenue par le programme
mycon?g fourni avec Perl, ou par perl -V) à <>. Si vous avez réussi à compiler Perl, le script perlbug fourni
dans le répertoire utils/ peut être utilisé pour envoyer un rapport de bug.
L’acronyme Perl signi?e réellement Pathologically Eclectic Rubbish Lister, mais ne dites à personne que je vous ai dit ça.
5

1.9. NOTES
perl
1.9
NOTES
La devise de Perl est "Il y a toujours plus d’une façon de le faire". Devinez exactement combien de façon est laissée en guise
d’exercice pour le lecteur.
Les trois grandes vertus du programmeur sont la paresse, l’impatience et l’orgueil. Reportez-vous au livre "Programmation en Perl"
pour savoir pourquoi.
1.10
VERSION FRANÇAISE
Cette traduction française correspond à la version anglaise distribuée avec perl 5.00502. Pour en savoir plus concernant ces traduc-
tions, consultez ;.
1.11
TRADUCTION
Marc Carmier <>
1.12
RELECTURE
Pascal Ethvignot <>
6

Chapitre 2
perlbook – Livres concernant Perl
Livres concernant Perl
2.1
DESCRIPTION
Le Camel Book (livre du chameau), of?ciellement appelé Programming Perl, Second Edition, par Larry Wall et al, est la référence
ultime en ce qui concerne Perl. Vous pouvez le commander ainsi que d’autres livres sur Perl depuis O’Reilly & Associates, 1-800-
998-9938 (aux usa). Pour l’international, +1 707 829 0515. Si vous pouvez récupérer un bon de commande O’Reilly, vous pouvez
aussi leur faxer à +1 707 829 0515. Si vous êtes connecté au Web, vous pouvez même surfer sur ;pour un bon
de commande en ligne.
D’autres livres concernant Perl provenant de divers éditeurs et auteurs peuvent être trouvés dans le manuel perlfaq3
2.2
VERSION FRANÇAISE
Cette traduction française correspond à la version anglaise distribuée avec perl 5.00502. Pour en savoir plus concernant ces traduc-
tions, consultez ;.
2.3
TRADUCTION
Mathieu Arnold <>
2.4
RELECTURE
Personne pour l’instant.
7

Chapitre 3
perlsyn – Syntaxe de Perl
Syntaxe de Perl
3.1
DESCRIPTION
Un script Perl est constitué d’une suite de déclarations et d’instructions.
La séquence d’instructions est exécutée une seule fois, contrairement aux scripts sed et awk, où la séquence est exécutée pour chaque
ligne en entrée. Même si cela signi?e que vous devez explicitement boucler sur les lignes de votre (ou de vos) ?chier(s) d’entrée,
cela veut aussi dire que vous avez bien plus de contrôle sur les ?chiers et les lignes que vous manipulez (en fait, je mens – il est
possible de faire une boucle implicite avec les options -n ou -p. Ce n’est juste pas le comportement par défaut comme avec sed et
awk).
Perl est, en majeure partie, un langage à syntaxe libre (La seule exception en est les déclarations de format, pour des raisons
évidentes). Le texte situé entre un caractère "#" et la ?n de la ligne est un commentaire, et est ignoré. Si vous essayez d’utiliser
/* */ pour des commentaires dans le style du C, ce sera interprété soit comme une division, soit comme un pattern matching, en
fonction du contexte, et les commentaires // du C++ auront juste l’air d’une expression régulière nulle, alors ne faites pas cela.
3.1.1
Declarations
Les seules choses que vous devez déclarer en Perl sont les formats de rapport et les sous-programmes – et même des sous-
programmes indé?nis peuvent être manipulés via AUTOLOAD. Une variable contient la valeur indé?nie (undef) jusqu’à ce qu’on
lui affecte une valeur, qui est n’importe quoi sauf undef. Lorsqu’il est utilisé comme un nombre, undef est traité comme 0 ; lorsqu’il
est utilisé comme une chaîne, il est traité comme la chaîne vide, "" ; et lorsqu’il est utilisé comme une référence qui n’a pas été
affectée, il est traité comme une erreur. Si vous validez les avertissements, vous serez noti?é de l’utilisation d’une valeur non ini-
tialisée chaque fois que vous traiterez undef comme une chaîne ou un nombre. En tout cas, habituellement. Les contextes booléens
("je-m’en-moque") et les opérateurs tels que ++, -, +=, -= et .= sont toujours exempts de tels avertissements.
Une déclaration peut être mise partout où une instruction peut trouver place, mais n’a pas d’effet sur l’exécution de la séquence
d’instructions principale - les déclarations prennent toutes effet au moment de la compilation. Typiquement, toutes les déclarations
sont placées au début ou à la ?n du script. Toutefois, si vous utilisez des variables privées de portée lexicales créées avec my(), vous
devrez vous assurez que la dé?nition de votre format ou de votre sous-programme est à l’intérieur du même bloc que le my si vous
voulez pouvoir accéder à ces variables privées.
La déclaration d’un sous-programme permet à un nom de sous-programme d’être utilisé comme s’il était un opérateur de liste à
partir de ce point dans le programme. Vous pouvez déclarer un sous-programme sans le dé?nir en disant sub name, ainsi :
sub myname;
$me = myname $0
or die "can’t get myname";
Notez que my fonctionne comme un opérateur de liste, pas comme un opérateur unaire ; faites donc attention d’utiliser or au lieu
de || dans ce cas. Toutefois, si vous déclariez le sous-programme avec sub myname ($), alors myname fonctionnerait comme un
opérateur unaire, donc or aussi bien que || feraient l’affaire.
Les déclarations de sous-programmes peuvent aussi être chargées à l’aide de l’instruction require ou bien à la fois chargées et
importées dans votre espace de noms via l’instruction use. Voir le manuel perlmod pour plus de détails.
Une séquence d’instructions peut contenir des déclarations de variables de portée lexicale, mais à part pour déclarer un nom de
variable, la déclaration fonctionne comme une instruction ordinaire, et est élaborée à l’intérieur de la séquence d’instructions en tant
que telle. Cela signi?e qu’elle a à la fois un effet à la compilation et lors de l’exécution.
8

3.1. DESCRIPTION
perlsyn
3.1.2
Instructions Simples
Le seul type d’instruction simple est une expression évaluée pour ses effets de bord. Chaque instruction simple doit être terminée
par un point-virgule, à moins qu’elle ne soit la dernière instruction d’un bloc, auquel cas le point-virgule est optionnel (Nous vous
encourageons tout de même à placer ce point-virgule si le bloc prend plus d’une ligne, car vous pourriez éventuellement ajouter une
autre ligne). Notez qu’il existe des opérateurs comme eval {} et do {} qui ont l’air d’instructions composées, mais qui ne le sont
pas (ce sont juste les TERMES d’une expression), et ont donc besoin d’une terminaison explicite s’ils sont utilisés comme dernier
élément d’une instruction.
Toute instruction simple peut être suivie de façon optionelle par un UNIQUE modi?cateur, juste avant le point-virgule de terminaison
(ou la ?n du bloc). Les modi?cateurs possibles sont :
if EXPR
unless EXPR
while EXPR
until EXPR
foreach EXPR
Les modi?cateurs if et unless ont la sémantique attendue, en supposant que vous parlez anglais. Le modi?cateur foreach est
un itérateur : il place successivement $_ à chaque valeur de EXPR et exécute l’instruction. Les modi?cateurs while et until ont
la sémantique habituelle "while loop" (la condition est évaluée en premier), sauf lorsqu’ils sont appliqués à un do-BLOC (ou à
l’instruction désapprouvée do-SOUS_PROGRAMME), auquel cas le bloc s’exécute une fois avant que la condition ne soit évaluée.
C’est ainsi pour que vous puissiez écrire des boucles telles que :
do {
$line = <STDIN>;

} until $line
eq ".\n";
Voir le titre do dans le manuel perlfunc. Notez aussi que l’instruction de contrôle de boucle décrite plus tard ne fonctionnera pas
dans cette construction, car les modi?cateurs n’utilisent pas de labels de boucle. Désolé. Vous pouvez toujours mettre un autre bloc
à l’intérieur (for next) ou autour (for last) pour réaliser ce genre de choses. Pour next, il suf?t de doubler les accolades :
do {{
next if $x == $y;
# do something here
}} until $x++ > $z;
Pour last, vous devez faire quelque chose de plus élaboré :
LOOP: {
do {
last if $x = $y**2;
# do something here
} while $x++ <= $z;
}
3.1.3
Instructions Composées
En Perl, une séquence d’instructions qui dé?nit une portée est appelée un bloc. Un bloc est parfois délimité par le ?chier qui le
contient (dans le cas d’un ?chier requis, ou dans celui du programme en entier), et parfois un bloc est délimité par la longueur d’une
chaîne (dans le cas d’un eval).
Mais généralement, un bloc est délimité par des accolades. Nous appellerons cette construction syntaxique un BLOC.
Les instructions composées suivantes peuvent être utilisées pour contrôler un ?ux :
if (EXPR) BLOC
if (EXPR) BLOC else BLOC
if (EXPR) BLOC elsif (EXPR) BLOC   else BLOC
LABEL while (EXPR) BLOC
LABEL while (EXPR) BLOC continue BLOC
LABEL for (EXPR; EXPR; EXPR) BLOC
LABEL foreach VAR (LIST) BLOC
LABEL foreach VAR (LIST) BLOCK continue BLOCK
LABEL BLOC continue BLOC
9

3.1. DESCRIPTION
perlsyn
Notez que, contrairement au C et au Pascal, tout ceci est dé?ni en termes de BLOCs, et non d’instructions. Ceci veut dire que
les accolades sont requises - aucune instruction ne doit traîner. Si vous désirez écrire des conditionnelles sans accolades, il existe
plusieurs autres façons de le faire. Les exemples suivants font tous la même chose :
if (!open(FOO)) { die "Can’t open $FOO: $!"; }
die "Can’t open $FOO: $!" unless open(FOO);
open(FOO) or die "Can’t open $FOO: $!";
# FOO or bust!
open(FOO) ? ’hi mom’ : die "Can’t open $FOO: $!";
# ce dernier est un peu exotique
L’instruction if est directe. Puisque les BLOCs sont toujours entourés d’accolades, il n’y a jamais d’ambiguïté pour savoir à quel
if correspond un else. Si vous utilisez unless à la place de if, le sens du test est inversé.
L’instruction while exécute le bloc tant que l’expression est vraie (son évaluation ne renvoie pas une chaîne nulle ("") ou 0 ou
"0"). Le LABEL est optionnel, et s’il est présent, il est constitué d’un identi?ant suivi de deux points. Le LABEL identi?e la boucle
pour les instructions de contrôle de boucle next, last, et redo. Si le LABEL est omis, l’instruction de contrôle de boucle se réfère
à la boucle incluse dans toutes les autres. Ceci peut amener une recherche dynamique dans votre pile au moment de l’exécution
pour trouver le LABEL. Un comportement aussi désespéré provoque un avertissement si vous utilisez le pragma use warnings ou
l’option -w. Contrairement à une instruction foreach, une instruction while ne localise jamais implicitement une variable.
S’il existe un BLOC continue, il est toujours exécuté juste avant que la condition ne soit à nouveau évaluée, de la même manière
que la troisième partie d’une boucle for en C. Il peut ainsi être utilisé pour incrémenter une variable de boucle, même lorsque la
boucle a été continuée via l’instruction next (qui est similaire à l’instruction continue en C).
3.1.4
Contrôle de Boucle
La commande next a le même rôle que l’instruction continue en C ; elle démarre la prochaine itération de la boucle :
LINE: while (<STDIN>) {
next LINE if /^#/;
# elimine les commentaires

}
La commande last est identique à l’instruction break en C (telle qu’elle est utilisée dans les boucles) ; elle sort immédiatement de
la boucle en question. Le bloc continue, s’il existe, n’est pas exécuté :
LINE: while (<STDIN>) {
last LINE if /^$/;
# sort quand on en a fini avec l’en-tete

}
La commande redo redémarre le bloc de la boucle sans réévaluer la condition. Le bloc continue, s’il existe, n’est pas exécuté.
Cette commande est normalement utilisée par les programmes qui veulent se mentir à eux-mêmes au sujet de ce qui vient de leur
être fourni en entrée.
Par exemple, lors du traitement d’un ?chier comme /etc/termcap. Si vos lignes en entrée sont susceptibles de se terminer par un
antislash pour indiquer leur continuation, vous pouvez vouloir poursuivre et récupérer l’enregistrement suivant.
while (<>) {
chomp;
if (s/\\$//) {
$_ .= <>;
redo unless eof();
}
# now process $_
}
qui est le raccourci Perl pour la version plus explicite :
LINE: while (defined($line = <ARGV>)) {
chomp($line);
if ($line =~ s/\\$//) {
$line .= <ARGV>;
redo LINE unless eof(); # pas eof(ARGV)!
}
# now process $line
}
10

3.1. DESCRIPTION
perlsyn
Notez que s’il y avait un bloc continue dans le code ci-dessus, il serait exécuté même pour les lignes rejetées. Ceci est souvent
utilisé pour réinitialiser les compteurs de lignes ou les recherches de motifs ?pat?.
# inspire par :1,$g/fred/s//WILMA/
while (<>) {
?(fred)?
&& s//WILMA $1 WILMA/;
?(barney)?
&& s//BETTY $1 BETTY/;
?(homer)?
&& s//MARGE $1 MARGE/;
} continue {
print "$ARGV $.: $_";
close ARGV
if eof();
# reinitialise $.
reset
if eof();
# reinitialise ?pat?
}
Si le mot while est remplacé par le mot until, le sens du test est inversé, mais la condition est toujours testée avant la première
itération.
Les instructions de contrôle de boucle ne fonctionnent pas dans un if ou dans un unless, puisque ce ne sont pas des boucles. Vous
pouvez toutefois doubler les accolades pour qu’elles le deviennent.
if (/pattern/) {{
next if /fred/;
next if /barney/;
# mettre quelque chose ici
}}
La forme while/if BLOC BLOC, disponible en Perl 4, ne l’est plus. Remplacez toutes les occurrences de if BLOC par if (do
BLOC).
3.1.5
Boucles For
Les boucles for de Perl dans le style de C fonctionnent exactement de la même façon que les boucles while correspondantes ; cela
signi?e que ceci :
for ($i = 1; $i < 10; $i++) {

}
est la même chose que ça :
$i = 1;
while ($i < 10) {

} continue {
$i++;
}
(Il existe une différence mineure : la première forme implique une portée lexicale pour les variables déclarées avec my dans l’expres-
sion d’initialisation).
En plus du bouclage classique dans les indices d’un tableau, for peut se prêter à de nombreuses autres applications intéressantes.
En voici une qui évite le problème que vous rencontrez si vous testez explicitement la ?n d’un ?chier sur un descripteur de ?chier
interactif, ce qui donne l’impression que votre programme se gèle.
$on_a_tty = -t STDIN && -t STDOUT;
sub prompt { print "yes? " if $on_a_tty }
for ( prompt(); <STDIN>; prompt() ) {
# faire quelque chose ici
}
11

3.1. DESCRIPTION
perlsyn
3.1.6
Boucles Foreach
La boucle foreach itère sur une liste de valeurs normale et ?xe la variable VAR à chacune de ces valeurs successivement. Si la
variable est précédée du mot-clé my, alors elle a une portée limitée du point de vue lexical, et n’est par conséquent visible qu’à
l’intérieur de la boucle. Autrement, la variable est implicitement locale à la boucle et reprend sa valeur précédente à la sortie de
la boucle. Si la variable était précédemment déclaré par my, elle utilise cette variable au lieu de celle qui est globale, mais elle est
toujours locale à la boucle.
Le mot-clé foreach est en fait un synonyme du mot-clé for, vous pouvez donc utiliser foreach pour sa lisibilité ou for pour sa
concision (Ou parce que le Bourne shell vous est plus familier que csh, vous rendant l’utilisation de for plus naturelle). Si VAR est
omis, $_ est ?xée à chaque valeur. Si un élément de LIST est une lvalue, vous pouvez la modi?er en modi?ant VAR à l’intérieur de
la boucle. C’est parce que la variable d’index de la boucle foreach est un alias implicite de chaque élément de la liste sur laquelle
vous bouclez.
Si une partie de LIST est un tableau, foreach sera très troublé dans le cas où vous lui ajouteriez ou retireriez des éléments à
l’intérieur de la boucle, par exemple à l’aide de splice. Ne faites donc pas cela.
foreach ne fera probablement pas ce que vous désirez si VAR est une variable liée ou une autre variable spéciale. Ne faites pas cela
non plus.
Exemples :
for (@ary) { s/foo/bar/ }
for my $elem (@elements) {
$elem *= 2;
}
for $count (10,9,8,7,6,5,4,3,2,1,’BOOM’) {
print $count, "\n"; sleep(1);
}
for (1..15) { print "Merry Christmas\n"; }
foreach $item (split(/:[\\\n:]*/, $ENV{TERMCAP})) {
print "Item: $item\n";
}
Voici comment un programmeur C pourrait coder un algorithme en Perl :
for (my $i = 0; $i < @ary1; $i++) {
for (my $j = 0; $j < @ary2; $j++) {
if ($ary1[$i] > $ary2[$j]) {
last; # ne peut pas sortir totalement :-(
}
$ary1[$i] += $ary2[$j];
}
# voici l’endroit ou ce last m’emmene
}
Tandis que voici comment un programmeur Perl plus à l’aise avec l’idiome pourrait le faire :
OUTER: for my $wid (@ary1) {
INNER:
for my $jet (@ary2) {
next OUTER if $wid > $jet;
$wid += $jet;
}
}
Vous voyez à quel point c’est plus facile ? C’est plus propre, plus sûr, et plus rapide. C’est plus propre parce qu’il y a moins de bruit.
C’est plus sûr car si du code est ajouté entre les deux boucles par la suite, le nouveau code ne sera pas exécuté accidentellement.
Le next itère de façon explicite sur l’autre boucle plutôt que de simplement terminer celle qui est à l’intérieur. Et c’est plus rapide
parce que Perl exécute une instruction foreach plus rapidement qu’une boucle for équivalente.
12

3.1. DESCRIPTION
perlsyn
3.1.7
BLOCs de Base et Instruction Switch
Un BLOC en lui-même (avec ou sans label) est d’un point de vue sémantique, équivalent à une boucle qui s’exécute une fois. Vous
pouvez donc y utilisez n’importe quelle instruction de contrôle de boucle pour en sortir ou le recommencer (Notez que ce n’est PAS
vrai pour les blocs eval{}, sub{}, ou do{} contrairement à la croyance populaire, qui NE comptent PAS pour des boucles). Le bloc
continue est optionnel.
La construction de BLOC est particulièrement élégante pour créer des structures case.
SWITCH: {
if (/^abc/) { $abc = 1; last SWITCH; }
if (/^def/) { $def = 1; last SWITCH; }
if (/^xyz/) { $xyz = 1; last SWITCH; }
$nothing = 1;
}
Il n’y a pas d’instruction switch of?cielle en Perl, car il existe déjà plusieurs façons d’écrire l’équivalent. Vous pourriez écrire à la
place de ce qui précède :
SWITCH: {
$abc = 1, last SWITCH
if /^abc/;
$def = 1, last SWITCH
if /^def/;
$xyz = 1, last SWITCH
if /^xyz/;
$nothing = 1;
}
(Ce n’est pas aussi étrange que cela en a l’air une fois que vous avez réalisé que vous pouvez utiliser des "opérateurs" de contrôle de
boucle à l’intérieur d’une expression, c’est juste l’opérateur virgule, normal en C).
ou
SWITCH: {
/^abc/ && do { $abc = 1; last SWITCH; };
/^def/ && do { $def = 1; last SWITCH; };
/^xyz/ && do { $xyz = 1; last SWITCH; };
$nothing = 1;
}
ou formaté de façon à avoir un peu plus l’air d’une instruction switch "convenable" :
SWITCH: {
/^abc/
&& do {
$abc = 1;
last SWITCH;
};
/^def/
&& do {
$def = 1;
last SWITCH;
};
/^xyz/
&& do {
$xyz = 1;
last SWITCH;
};
$nothing = 1;
}
ou
SWITCH: {
/^abc/ and $abc = 1, last SWITCH;
/^def/ and $def = 1, last SWITCH;
/^xyz/ and $xyz = 1, last SWITCH;
$nothing = 1;
}
13

3.1. DESCRIPTION
perlsyn
or même, horreur,
if (/^abc/)
{ $abc = 1 }
elsif (/^def/)
{ $def = 1 }
elsif (/^xyz/)
{ $xyz = 1 }
else
{ $nothing = 1 }
Un idiome courant pour une instruction switch est d’utiliser l’aliasing de foreach pour effectuer une affectation temporaire de $_
pour une reconnaissance pratique des cas :
SWITCH: for ($where) {
/In Card Names/
&& do { push @flags, ’-e’; last; };
/Anywhere/
&& do { push @flags, ’-h’; last; };
/In Rulings/
&& do {
last; };
die "unknown value for form variable where: ‘$where’";
}
Une autre approche intéressante de l’instruction switch est de s’arranger pour qu’un bloc do renvoie la valeur correcte :
$amode = do {
if
($flag & O_RDONLY) { "r" }
# XXX : n’est-ce pas 0?
elsif
($flag & O_WRONLY) { ($flag & O_APPEND) ? "a" : "w" }
elsif
($flag & O_RDWR)
{
if ($flag & O_CREAT)
{ "w+" }
else
{ ($flag & O_APPEND) ? "a+" : "r+" }
}
};
ou
print do {
($flags & O_WRONLY) ? "write-only"
:
($flags & O_RDWR)
? "read-write"
:
"read-only";
};
Ou si vous êtes certain que toutes les clauses && sont vraies, vous pouvez utiliser quelque chose comme ceci, qui "switche" sur la
valeur de la variable d’environnement HTTP_USER_AGENT.
#!/usr/bin/perl
# choisir une page du jargon file selon le browser
$dir = ’’;
for ($ENV{HTTP_USER_AGENT}) {
$page
=
/Mac/
&& ’’
|| /Win(dows )?NT/
&& ’’
|| /Win|MSIE|WebTV/ && ’’
|| /Linux/
&& ’’
|| /HP-UX/
&& ’’
|| /SunOS/
&& ’’
||
’’;
}
print "Location: $dir/$page\015\012\015\012";
Ce type d’instruction switch ne fonctionne que lorsque vous savez que les clauses && seront vraies. Si vous ne le savez pas, l’exemple
précédent utilisant ?: devrait être utilisé.
Vous pourriez aussi envisager d’écrire un hachage de références de sous-programmes au lieu de synthétiser une instruction switch.
14

3.1. DESCRIPTION
perlsyn
3.1.8
Goto
Bien que cela ne soit pas destiné aux âmes sensibles, Perl supporte une instruction goto. Il en existe trois formes : goto-LABEL,
goto-EXPR, et goto-&NAME. Un LABEL de boucle n’est pas en vérité une cible valide pour un goto ; c’est juste le nom de la
boucle.
La forme goto-LABEL trouve l’instruction marquée par LABEL et reprend l’exécution à cet endroit. Elle ne peut pas être utilisée
pour aller dans une structure qui nécessite une initialisation, comme un sous-programme ou une boucle foreach. Elle ne peut pas
non plus être utilisée pour aller dans une structure très optimisée. Elle peut être employée pour aller presque n’importe où ailleurs
à l’intérieur de la portée dynamique, y compris hors des sous-programmes, mais il est habituellement préférable d’utiliser une autre
construction comme last ou die. L’auteur de Perl n’a jamais ressenti le besoin d’utiliser cette forme de goto (en Perl, à vrai dire -
C est une toute autre question).
La forme goto-EXPR attend un nom de label, dont la portée sera résolue dynamiquement. Ceci permet des gotos calculés à la mode
de FORTRAN, mais ce n’est pas nécessairement recommandé si vous optimisez la maintenance du code :
goto(("FOO", "BAR", "GLARCH")[$i]);
La forme goto-&NAME est hautement magique, et substitue au sous-programme en cours d’exécution un appel au sous-programme
nommé. C’est utilisé par les sous-programmes AUTOLOAD() qui veulent charger une autre routine et prétendre que cette autre routine
a été appelée à leur place (sauf que toute modi?cation de @_ dans le sous-programme en cours est propagée à l’autre routine). Après
le goto, même caller() ne pourra pas dire que cette routine n’a pas été appelée en premier.
Dans presque tous les cas similaires, une bien, bien meilleure idée est d’utiliser les mécanismes de contrôle de ?ux structurés comme
next, last, ou redo au lieu de s’en remettre à un goto. Pour certaines applications, la paire eval{} - die() pour le traitement des
exceptions peut aussi être une approche prudente.
3.1.9
POD : Documentation Enfouie
Perl dispose d’un mécanisme pour mélanger de la documentation avec le code source. Lorsqu’il s’attend au début d’une nouvelle
instruction, si le compilateur rencontre une ligne commençant par un signe égal et un mot, comme ceci
=head1 Here There Be Pods!
Alors ce texte et tout ce qui suit jusqu’à et y compris une ligne commençant par =cut sera ignoré. Le format du texte en faisant partie
est décrit dans le manuel perlpod.
Ceci vous permet de mélanger librement votre code source et votre documentation, comme dans
=item snazzle($)
La fonction snazzle() se comportera de la facon la plus spectaculaire que
vous pouvez imaginer, y compris la pyrotechnie cybernetique.
=cut retour au compilateur, nuff of this pod stuff!
sub snazzle($) {
my $thingie = shift;

}
Notez que les traducteurs pod ne devraient traiter que les paragraphes débutant par une directive pod (cela rend leur analyse plus
simple), tandis que le compilateur sait en réalité chercher des séquences pod même au milieu d’un paragraphe. Cela veut que le
matériel secret qui suit sera ignoré à la fois par le compilateur et les traducteurs.
$a=3;
=truc secret
warn "Neither POD nor CODE!?"
=cut back
print "got $a\n";
Vous ne devriez probablement pas vous reposer sur le fait que le warn() sera ignoré pour toujours. Les traducteurs pod ne sont pas
tous bien élevés de ce point de vue, et le compilateur deviendra peut-être plus regardant.
On peut aussi utiliser des directives pod pour mettre rapidement une partie de code en commentaire.
15

3.2. VERSION FRANÇAISE
perlsyn
3.1.10
Bons Vieux Commentaires (Non !)
À la manière du préprocesseur C, Perl peut traiter des directives de ligne. Avec cela, on peut contrôler l’idée que Perl se fait des noms
de ?chiers et des numéros de ligne dans les messages d’erreur ou dans les avertissements (en particulier pour les chaînes traitées
par eval()). La syntaxe de ce mécanisme est la même que pour pour la plupart des préprocesseurs C : elle reconnaît l’expression
régulière /ˆ#\s*line\s+(\d+)\s*(?:\s"([ˆ"]*)")?/\s*$/ où $1 est le numéro de la prochaine ligne, et $2 le nom de ?chier
optionnel (spéci?é entre apostrophes).
Voici quelques exemples que vous devriez pouvoir taper dans votre interpréteur de commandes :
% perl
# line 200 "bzzzt"
# the ‘#’ on the previous line must be the first char on line
die ’foo’;
__END__
foo at bzzzt line 201.
% perl
# line 200 "bzzzt"
eval qq[\n#line 2001 ""\ndie ’foo’]; print $@;
__END__
foo at - line 2001.
% perl
eval qq[\n#line 200 "foo bar"\ndie ’foo’]; print $@;
__END__
foo at foo bar line 200.
% perl
# line 345 "goop"
eval "\n#line " . __LINE__ . ’ "’ . __FILE__ ."\"\ndie ’foo’";
print $@;
__END__
foo at goop line 345.
3.2
VERSION FRANÇAISE
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.0. Pour en savoir plus concernant ces traductions,
consultez ;.
3.3
TRADUCTION
Roland Trique <>
3.4
RELECTURE
Régis Julié <> Etienne Gauthier <>
16

Chapitre 4
perldata – Types de données de Perl
Types de données de Perl
4.1
DESCRIPTION
4.1.1
Noms des variables
Perl a trois types de données intégrés : les scalaires, les tableaux de scalaires, et les tableaux associatifs de scalaires, appelés "ha-
chages". Les tableaux normaux sont des listes ordonnées de scalaires indexées par des nombres, en commençant par 0 et où les
indices négatifs sont comptés depuis la ?n. Les tables de hachages sont des collections non ordonnées de valeurs scalaires indexées
par des chaînes qui sont leurs clés associées.
On fait habituellement référence aux valeurs par leur nom, ou par une référence nommée. Le premier caractère du nom vous indique à
quel type de structure de données il correspond. Le reste du nom vous dit à quelle valeur particulière il fait référence. Habituellement,
ce nom est un simple identi?ant, c’est-à-dire une chaîne commençant par une lettre ou un caractère souligné, et contenant des lettres,
des soulignés, et des chiffres. Dans certains cas, il peut être une chaîne d’identi?ants, séparés par :: (ou par le légèrement archaïque
’) ; tous sauf le dernier sont interprétés comme des noms de paquetages, pour localiser l’espace de nommage dans lequel l’identi?ant
?nal doit être recherché (voir le titre Paquetages dans le manuel perlmod pour plus de détails). Il est possible de substituer à un
simple identi?ant une expression qui produit une référence à la valeur lors de l’exécution. Ceci est décrit plus en détails plus bas, et
dans le manuel perlref.
Perl a aussi ses propres variables intégrées dont les noms ne suivent pas ces règles. Elles ont des noms étranges pour qu’elles ne
rentrent pas accidentellement en collision avec l’une de vos variables normales. Les chaînes qui correspondent aux parties entre
parenthèses d’une expression rationnelle sont sauvées sous des noms qui ne contiennent que des chiffres après le $ (voir le manuel
perlop et le manuel perlre). De plus, plusieurs variables spéciales qui ouvrent des fenêtres dans le fonctionnement interne de Perl
ont des noms contenant des signes de ponctuation et des caractères de contrôle. Elles sont décrites dans le manuel perlvar.
Les valeurs scalaires sont toujours désignées par un ’$’, même si l’on se réfère à un scalaire qui fait partie d’un tableau ou d’un
hachage. Le symbole ’$’ fonctionne d’un point de vue sémantique comme les mots "le", "la". Ainsi, nous avons :
$days
# la simple valeur scalaire "days"
$days[28]
# le 29ème élément du tableau @days
$days{’Feb’}
# la veleur ’Feb’ dans le hachage %days
$#days
# le dernier indice du tableau @days
Les tableaux complets (et les tranches de tableaux ou de hachages) sont dénotés par ’@’, qui fonctionne plutôt comme le mot "ces",
en ce sens qu’il indique que des valeurs multiples sont attendues :
@days
# ($days[0], $days[1],  $days[n])
@days[3,4,5]
# identique à ($days[3],$days[4],$days[5])
@days{’a’,’c’}
# identique à ($days{’a’},$days{’c’})
Les hachages complets sont dénotés par ’%’ :
%days
# (clé1, valeur1, clé2, valeur2  )
17

4.1. DESCRIPTION
perldata
De plus, les sous-programmes sont nommés avec un ’&’ initial, bien que ce soit optionel lorsqu’il n’y a pas d’ambigüité, tout comme
"faire" est souvent redondant en français. Les entrées des tables de symboles peuvent être nommées avec un ’*’ initial, mais vous ne
vous souciez pas vraiment de cela pour le moment (si jamais :-).
Chaque type de variable a son propre espace de nommage, tout comme identi?ants de plusieurs types autres que les variables. Ceci
signi?e que vous pouvez, sans craindre un con?it, utiliser le même nom pour une variable scalaire, un tableau, ou un hachage – ou,
pour cette affaire, un handle de ?chier, un handle de répertoire, un nom de sous-programme, ou un label. Ceci veut dire que $foo et
@foo sont deux variables différentes. Ceci veut aussi dire que $foo[1] fait partie de @foo, et pas de $foo. Cela peut sembler un peu
étrange, mais c’est normal, puisque c’est étrange.
Puisque les références de variables commencent toujours par ’$’, ’@’, ou ’%’, les mots "réservés" ne sont en fait pas réservés en ce
qui concerne les noms de variables (Ils SONT toutefois réservés en ce qui concerne les labels et les handles de ?chiers, qui n’ont
pas de caractère spécial initial. Vous ne pouvez pas avoir un handle de ?chier nommé "log", par exemple. Indice : vous pourriez dire
open(LOG,’logfile’) plutôt que open(log,’logfile’). Utiliser des handles de ?chiers en lettres majuscules améliore aussi
la lisibilité et vous protège de con?its avec de futurs mots réservés. La casse est signi?cative – "FOO", "Foo", et "foo" sont tous
des noms différents. Les noms qui commencent par une lettre ou un caractère souligné peuvent aussi contenir des chiffres et des
soulignés.
Il est possible de remplacer un tel nom alphanumérique par une expression qui retourne une référence au type approprié. Pour une
description de ceci, voir le manuel perlref.
Les noms qui commencent par un chiffre ne peuvent contenir que des chiffres. Les noms qui ne commencent pas par une lettre, un
souligné ou un chiffre sont limités à un caractère, e.g., $% or $$ (La plupart de ces noms d’un seul caractère ont une signi?cation
prédé?nie pour Perl. Par exemple, $$ est l’id. du processus courant).
4.1.2
Contexte
L’interprétation des opérations et des valeurs en Perl dépend parfois des exigences du contexte de l’opération ou de la valeur. Il
existe deux contextes majeurs : le contexte de liste et le contexte scalaire. Certaines opérations retournent des valeurs de liste dans
les contextes qui réclament une liste, et des valeurs scalaires autrement Ssi ceci est vrai pour une opération alors cela sera mentionné
dans la documentation pour cette opération. En d’autres termes, Perl surcharge certaines opérations selon que la valeur de retour
attendue est singulière ou plurielle. Certains mots en français fonctionnent aussi de cette façon, comme "lys" et "dos".
Réciproquement, une opération fournit un contexte scalaire ou de liste à chacun de ses arguments. Par exemple, si vous dites
int( <STDIN> )
L’opération int fournit un contexte scalaire pour l’opérateur <STDIN>, qui répond en lisant une ligne depuis STDIN et en la passant
à l’opération int, qui trouvera alors la valeur entière de cette ligne et retournera cela. Si, au contraire, vous dites
sort( <STDIN> )
alors l’opération sort fournit un contexte de liste pour <STDIN>, qui se mettra à lire toutes les lignes disponibles jusqu’à la ?n du
?chier, et passera cette liste de lignes à la routine de tri, qui triera alors ces lignes et les retournera en tant que liste à ce qui est le
contexte de sort, quel qu’il soit.
L’affectation est un petit peu spéciale en ce sens qu’elle utilise son argument gauche pour déterminer le contexte de l’argument droit.
L’affectation à un scalaire évalue la partie droite dans un contexte scalaire, tandis que l’affectation à un tableau ou à un hachage
évalue la partie droite dans un contexte de liste. L’affectation à une liste (ou à une tranche, qui est juste une liste de toute façon)
évalue aussi la partie droite dans un contexte de liste.
Lorsque vous utilisez le pragma use warnings ou l’option de ligne de commande -w de Perl, il arrive que vous voyiez des avertis-
sements sur un usage inutile de constantes ou de fonctions dans un "contexte vide" ("void context", NDT). Le contexte vide signi?e
juste que la valeur a été abandonnée, comme pour une instruction ne contenant que "fred"; ou getpwuid(0);. Il compte toujours
pour un contexte scalaire pour les fonctions qui se soucient de savoir si elles sont ou non appelées dans un contexte scalaire.
Les sous-programmes dé?nis par l’utilisateur peuvent se soucier d’avoir été appelés dans un contexte vide, scalaire ou de liste. La
plupart des sous-programmes n’en ont toutefois pas besoin. C’est parce que les scalaires et les listes sont automatiquement interpolés
en listes. Voir le titre wantarray dans le manuel perlfunc pour une façon dont vous pourriez discerner dynamiquement le contexte
d’appel de votre fonction.
18

4.1. DESCRIPTION
perldata
4.1.3
Valeurs scalaires
Toute donnée en Perl est un scalaire, un tableau de scalaires ou un hachage de scalaires. Les variables scalaires peuvent contenir des
une seule valeur de trois formes différentes : un nombre, une chaîne ou une référence. En général, la conversion d’une forme à une
autre est transparente. Bien qu’un scalaire ne puisse pas contenir des valeurs multiples, il peut contenir une référence à un tableau
ou à un hachage qui à son tour contient des valeurs multiples.
Les scalaires ne sont pas nécessairement une chose ou une autre. Il n’y a pas d’endroit où déclarer qu’une variable scalaire doit
être de type "chaîne", de type "nombre", de type "référence", ou n’importe quoi d’autre. Du fait de la conversion automatique des
scalaires, les opérations qui en retournent n’ont pas besoin de se soucier (et en fait ne le peuvent pas) de savoir si leur appelant
attend une chaîne, un nombre ou une référence. Perl est un langage contextuellement polymorphe dont les scalaires peuvent être
des chaînes, des nombres, ou des références (ce qui inclut les objets). Tandis que les chaînes et les nombres sont considérés comme
presque la même chose pour pratiquement tous les usages, les références sont des pointeurs au typage fort et impossible à forcer,
avec comptage de référence intégré et invocation de destructeur.
Une valeur scalaire est interprétée comme TRUE (VRAIE, NDT) au sens booléen si ce n’est pas une chaîne vide ou le nombre 0 (ou
sous équivalent sous forme de chaîne, "0"). Le contexte booléen est juste un genre spécial de contexte scalaire, où aucun conversion
vers une chaîne ou un nombre n’est jamais effectuée.
Il existe en fait deux variétés de chaînes nulles (parfois appelées des chaînes "vides"), l’une dé?nie et l’autre non. La version dé?nie
est juste une chaîne de longueur zéro, telle que "". La version non dé?nie est la valeur qui indique qu’il n’existe pas de vraie valeur
pour quelque chose, comme lorsqu’il s’est produit une erreur, ou à la ?n d’un ?chier, ou lorsque vous vous référez à une variable
ou à un élément de tableau ou de hachage non initialisé. Bien que dans les anciennes versions de Perl, un scalaire indé?ni ait pu
devenir dé?ni lorsqu’il était utilisé pour la première fois dans un endroit où une valeur dé?nie était attendue, cela ne se produit plus,
sauf dans de rares cas d’autovivi?cation tels qu’expliqués dans le manuel perlref. Vous pouvez utiliser l’opérateur de?ned() pour
déterminer si une valeur scalaire est dé?nie (cela n’a pas de sens pour les tableaux ou les hachages), et l’opérateur undef() pour
produire une valeur indé?nie.
Pour trouver si une chaîne donnée est un nombre différent de zéro valide, il suf?t parfois de la tester à la fois avec le 0 numérique
et le "0" lexical (bien que ceci provoquera du bruit en provenance de -w). C’est parce que les chaînes qui ne sont pas des nombres
comptent comme 0, tout comme en awk :
if ($str == 0 && $str ne "0")
{
warn "That doesn’t look like a number";
}
Cette méthode est peut-être meilleure parce qu’autrement vous ne traiteriez pas correctement les notations IEEE comme NaN ou
Infinity. À d’autres moments, vous pourriez préférer déterminer si une donnée chaîne peut être utilisée numériquement en appelant
la fonction POSIX::strtod() ou en inspectant votre chaîne avec une expression rationnelle (tel que documenté dans le manuel perlre).
warn "has nondigits"
if
/\D/;
warn "not a whole number"
unless /^\d+$/;
warn "not an integer"
unless /^[+-]?\d+$/
warn "not a decimal number" unless /^[+-]?\d+\.?\d*$/
warn "not a C float"
unless /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/;
La longueur d’un tableau est une valeur scalaire. Vous pourriez trouver la longueur du tableau @days en évaluant $#days, comme
en csh. D’un point de vue technique, ce n’est pas la longueur du tableau ; c’est l’indice de son dernier élément, parce qu’il y a
ordinairement un élément numéro 0. Une affectation à $#days change véritablement la longueur du tableau. Le raccourcissement
d’un tableau par cette méthode détruit les valeurs intermédiaires. L’agrandissement d’un tableau ayant précédemment été raccourci
ne récupère pas les valeurs qui étaient stockées dans ces éléments (c’était le cas en Perl 4, mais nous avons dû supprimer cela pour
nous assurer que les destructeurs sont bien appelés quand on s’y attend).
Vous pouvez aussi gagner en ef?cacité en pré-étendant un tableau qui va devenir gros (vous pouvez aussi étendre un tableau en
affectant des données à un élément qui est au-delà de la ?n du tableau). Vous pouvez tronquer totalement un tableau en y affectant la
liste vide (). Les expressions suivantes sont équivalentes :
@whatever = ();
$#whatever = -1;
Si vous évaluez un tableau dans un contexte scalaire, cela renvoit la longueur du tableau (notez que ceci n’est pas vrai pour les
listes, qui renvoient leur dernière valeur, comme l’opérateur virgule en C, et contrairement aux fonctions intégrées, qui renvoient ce
qu’elles ont envie de renvoyer). Ce qui suit est toujours vrai :
scalar(@whatever) == $#whatever - $[ + 1;
19

4.1. DESCRIPTION
perldata
La version 5 de Perl a changé la sémantique de $[ : les ?chiers qui ne ?xent pas la valeur de $[ n’ont plus besoin de s’inquiéter
de savoir si un autre ?chier a changé sa valeur (en d’autres termes, l’usage de $[ est désapprouvé). Donc de façon générale, vous
pouvez présumer que
scalar(@whatever) == $#whatever + 1;
Certains programmeurs choisissent d’utiliser une conversion explicite pour ne rien laisser au hasard :
$element_count = scalar(@whatever);
Si vous évaluez un hachage dans un contexte scalaire, vous obtenez faux si le hachage est vide. S’il contient une paire clé/valeur
quelconque, il renvoie vrai ; plus précisément, la valeur retournée est une chaîne constituée du nombre de buckets utilisés et du
nombre de buckets alloués, séparés par un signe de division. Ceci n’a tendance à être très utile que pour déterminer si les algorithmes
de hachage (compilés) en Perl ont des performances médiocres sur vos données. Par exemple, vous mettez 10.000 trucs dans un
hachage, mais l’évaluation de %HASH dans un contexte scalaire révèle "1/16", ce qui signi?e qu’un seul des seize buckets a été
touché, et contient probablement tous vos 10,000 éléments. Cela ne devrait pas se produire).
4.1.4
Constructeurs de valeurs scalaires
Les littéraux numériques sont spéci?és dans un quelconque des formats suivants de nombres entiers ou à virgule ?ottante :
12345
12345.67
.23E-10
# un très petit nombre
4_294_967_296
# souligné pour la lisibilité
0xff
# hexa
0377
# octal
0b011011
# binaire
Les littéraux de chaîne sont habituellement délimités soit par des apostrophes, soit par des guillemets. Ils fonctionnent beaucoup
comme dans un shell Unix standard : les littéraux de chaîne entre guillemets sont sujets aux substitutions de variables et au pré?xage
par barre oblique inverse ; les chaînes entre apostrophes ne le sont pas (sauf pour \’ et \\). Les règles habituelles d’utilisation de la
barre oblique inverse en C s’appliquent aussi bien pour créer des caractères comme la nouvelle ligne, la tabulation, etc., que sous des
formes plus exotiques. Voir le titre Opérateurs apostrophe et type apostrophe dans le manuel perlop pour une liste.
Les représentations hexadécimales, octales ou binaires sous formes de chaînes (e.g. ’0xff’) ne sont pas automatiquement converties
sous leur représentation entière. Les fonctions hex() et oct() font ces conversions pour vous. Voir le titre hex dans le manuel perlfunc
et le titre oct dans le manuel perlfunc pour plus de détails.
Vous pouvez aussi inclure des "nouvelles lignes" directement dans vos chaînes, i.e., elles peuvent se terminer sur une ligne différente
de celles où elles ont commencé. C’est bien joli, mais si vous oubliez votre apostrophe de ?n (ou votre guillemet - NDT), l’erreur ne
sera pas rapportée avant que Perl n’ait trouvé une autre ligne comportant une apostrophe, qui peut se trouver bien plus loin dans le
script. La substitution de variable à l’intérieur des chaînes est limitée aux variables scalaires, aux tableaux et aux tranches de tableau
ou de hachage (en d’autres termes, des noms commençant par $ ou @, suivi d’une expression optionnelle entre crochets comme
indice). Le segment de code qui suit af?che "The price is $100."
$Price = ’$100’;
# pas interprété
print "The price is $Price.\n";
# interprété
Comme dans certains shells, vous pouvez mettre des accolades autour d’un nom pour le séparer des caractères alphanumériques qui
le suivent. Vous devez aussi faire cela lorsque vous interpolez une variable dans une chaîne pour séparer son nom d’un deux-points
ou d’une apostrophe, puisqu’ils seraient autrement traités comme un séparateur de paquetage :
$who = "Larry";
print PASSWD "${who}::0:0:Superuser:/:/bin/perl\n";
print "We use ${who}speak when ${who}’s here.\n";
Sans les accolades, Perl aurait cherché un $whospeak, un $who::0, et une variable who’s. Les deux dernières auraient été les
variables $0 et $s dans le paquetage who (probablement) inexistant.
En fait, un identi?ant situé entre de telles accolades est forcé d’être une chaîne, tout comme l’est tout identi?cateur isolé à l’intérieur
d’un indice d’un hachage. Aucun des deux n’a besoin d’apostrophes. Notre exemple précédent, $days{’Feb’} peut être écrit sous
la forme $days{Feb} et les apostrophes seront présumées automatiquement. Mais tout ce qui est plus compliqué dans l’indice sera
interprété comme étant une expression.
20

4.1. DESCRIPTION
perldata
Un littéral de la forme v1.20.300.4000 est analysé comme une chaîne composée de caractères correspondants aux ordinaux spé-
ci?és. Ceci fournit une façon alternative plus lisible pour construire des chaînes, au lieu d’utiliser l’interpolation quelque peu moins
lisible "\x{1}\x{14}\x{12c}\x{fa0}". C’est utile pour représenter des chaînes Unicode, et pour comparer des numéros de version
en utilisant les opérateurs de comparaison de chaînes, cmp, gt, lt etc. Si le littéral contient plusieurs points, le premier v peut être
omis.
print v9786;
# affiche le SMILEY codé en UTF-8,
# "\x{263a}"
print v102.111.111;
# affiche "foo"
print 102.111.111;
# idem
De tels littéraux sont acceptés à la fois par require et use pour réaliser une véri?cation de numéro de version. La variable spéciale
$ˆV contient aussi le numéro de version sous cette forme de l’interpréteur Perl en cours d’utilsation. Voir le titre $ˆV dans le manuel
perlvar.
Les littéraux spéciaux __FILE__, __LINE__, et __PACKAGE__ représentent le nom de ?chier courant, le numéro de la ligne, et
le nom du paquetage à ce point de votre programme. Ils ne peuvent être utilisés que comme des mots-clé isolés ; ils ne seront pas
interpolés dans les chaînes. S’il n’existe pas de paquetage courant (à cause d’une directive package;), __PACKAGE__ est la valeur
indé?nie.
Les deux caractères de contrôle ˆD et ˆZ, et les mots-clé __END__ et __DATA__ peuvent être utilisés pour indique la ?n logique
d’un script avant la ?n effective du ?chier. Tout texte les suivant est ignoré.
Le texte qui suit __DATA__ peut être lu via le handle de ?chier PACKNAME::DATA, où PACKNAME est le paquetage qui était courant
lorsque le mot-clé __DATA__ a été rencontré. Le handle de ?chier est laissé ouvert, pointant vers le contenu après __DATA__. Il est
de la responsabilité du programme d’effectuer un close DATA lorsqu’il a ?ni d’y lire. Pour la compatibilité avec d’anciens scripts
écrits avant que __DATA__ ne soit introduit, __END__ se comporte comme __DATA__ dans le script principal (mais pas dans les
?chiers chargés par require ou do) et laisse le contenu restant du ?chier accessible via main::DATA.
Voir le manuel SelfLoader pour une plus longue description de __DATA__, et un exemple de son utilisation. Notez que vous ne
pouvez pas lire depuis le handle de ?chier DATA dans un bloc BEGIN : ce bloc est exécuté dès qu’il est vu (pendant la compilation),
à un moment où le mot-clé __DATA__ (ou __END__) correspondant n’a pas encore été rencontré.
Un mot qui n’a aucune autre interprétation dans la grammaire sera traité comme s’il était une chaîne entre apostrophes. Ces mots
sont connus sous le nom de "barewords". Comme pour les handles de ?chier et les labels, un bareword constitué entièrement de
lettres minuscules risque d’entrer en con?it avec de futurs mots réservés, et si vous utilisez le pragma use warnings ou l’option
-w, Perl vous avertira pour chacun d’entre eux. Certaines personnes pourraient vouloir rendre les barewords totalement hors-la-loi.
Si vous dites
use strict ’subs’;
alors tout bareword qui ne serait PAS interprété comme un appel à un sous-programme produit à la place une erreur au moment de la
compilation. La restriction continue jusqu’à la ?n du bloc qui le contient. Un bloc interne pourrait annuler ceci en disant no strict
’subs’.
Les tableaux et les tranches sont interpolés en chaînes entre guillemets en joignant tous les éléments avec le délimiteur spéci?é dans la
variable $" ($LIST_SEPARATOR dans le paquetage ), une espace par défaut. Les expressions suivantes sont équivalentes :
$temp = join($", @ARGV);
system "echo $temp";
system "echo @ARGV";
À l’intérieur d’un motif de recherche (qui subit aussi la substitution entre guillemets) il y a une malheureuse ambigüité : est-ce que
/$foo[bar]/ doit être interprété comme /${foo}[bar]/ (où [bar] est une classe de caractères pour l’expression régulière) ou
comme /${foo[bar]}/ (où [bar] est un indice du tableau @foo)? Si @foo n’existe pas par ailleurs, alors c’est évidemment une
classe de caractères. Si @foo existe, Perl choisit de deviner la valeur de [bar], et il a presque toujours raison. S’il se trompe, ou si
vous êtes simplement complètement paranoïaque, vous pouvez forcer l’interprétation correcte avec des accolades comme ci-dessus.
Une forme de citation orientée ligne est basée sur la syntaxe "here-document" du shell. Après un « vous spéci?ez une chaîne pour
terminer le matériel cité, et toutes les lignes qui suivent la ligne courante jusqu’à la chaîne de terminaison forment la valeur de
l’élément. La chaîne de terminaison peut être soit un identi?cateur (un mot), ou du texte cité. S’il est entre guillemets, le type de
guillemets que vous utilisez détermine le traitement du texte, tout comme dans une citation normale. Un identi?cateur sans guillemets
fonctionne comme des guillemets normaux. Il ne doit pas y avoir d’espace entre le « et l’identi?cateur (si vous mettez une espace,
elle sera traitée comme un identi?cateur nul, ce qui est valide, et correspond à la première ligne vide). La chaîne de terminaison doit
apparaître toute seule (sans guillemets et sans espaces l’entourant) sur la ligne de terminaison.
21

4.1. DESCRIPTION
perldata
print <<EOF;
The price is $Price.
EOF
print <<"EOF";
# comme ci-dessus
The price is $Price.
EOF
print <<‘EOC‘;
# exécute les commandes
echo hi there
echo lo there
EOC
print <<"foo", <<"bar";
# vous pouvez les empiler
I said foo.
foo
I said bar.
bar
myfunc(<<"THIS", 23, <<’THAT’);
Here’s a line
or two.
THIS
and here’s another.
THAT
N’oubliez simplement pas que vous devez mettre un point-virgule à la ?n pour terminer la déclaration, car Perl ne sait pas que vous
n’allez pas essayer de faire ceci :
print <<ABC
179231
ABC
+ 20;
Si vous désirez que vos here-documents soient indentés avec le reste du code, vous devrez retirer manuellement la première espace
de chaque ligne :
($quote = <<’FINIS’) =~ s/^\s+//gm;
The Road goes ever on and on,
down from the door where it began.
FINIS
4.1.5
Constructeurs de listes de valeurs
Les valeurs de liste sont dénotées en séparant les valeurs individuelles par des virgules (et en enfermant la liste entre parenthèses
lorsque la précédence le requiert) :
(LIST)
Dans un contexte qui ne requiert pas une valeur de liste, la valeur de ce qui apparaît être un littéral de liste est simplement la valeur
de l’élément ?nal, comme avec l’opérateur virgule en C. Par exemple,
@foo = (’cc’, ’-E’, $bar);
affecte la totalité de la valeur de liste au tableau @foo, mais
$foo = (’cc’, ’-E’, $bar);
affecte la valeur de la variable $bar à la variable $foo. Notez que la valeur d’un véritable tableau dans un contexte scalaire est la
longueur du tableau ; ce qui suit affecte la valeur 3 à $foo :
@foo = (’cc’, ’-E’, $bar);
$foo = @foo;
# $foo prend la valeur 3
22

4.1. DESCRIPTION
perldata
Vous pouvez avoir une virgule optionnelle avant la parenthèse fermante d’un littéral de liste, vous pouvez donc dire :
@foo = (
1,
2,
3,
);
Pour utiliser un here-document a?n d’affecter un tableau, une ligne par élément, vous pourriez utiliser l’approche suivante :
@sauces = <<End_Lines =~ m/(\S.*\S)/g;
normal tomato
spicy tomato
green chile
pesto
white wine
End_Lines
Les LIST font une interpolation automatique des sous-listes. C’est-à-dire que lorsqu’une LIST est évaluée, chaque élément de la
liste est évalué dans un contexte de liste, et la valeur de liste résultante est interpolée en LIST tout comme si chaque élément était un
membre de LIST. Ainsi les tableaux perdent leur identité dans une LIST - la liste
(@foo,@bar,&SomeSub)
contient tous les éléments de @foo suivis par tous les éléments de @bar, suivis par tous les éléments retournés par le sous-programme
appelé SomeSub quand il est appelé dans un contexte de liste. Pour faire une référence à une liste qui NE soit PAS interpolée, voir le
manuel perlref.
La liste vide est représentée par (). L’interpoler dans une liste n’a aucun effet. Ainsi, ((),(),()) est équivalent à (). De façon similaire,
interpoler un tableau qui ne contient pas d’élément revient à ce qu’aucun tableau n’ait été interpolé à ce moment-là.
Une valeur de liste peut aussi être indicée comme un tableau normal. Vous devez mettre la liste entre parenthèses pour éviter les
ambiguïtés. Par exemple :
# Stat renvoit une valeur de liste.
$time = (stat($file))[8];
# ICI, ERREUR DE SYNTAXE.
$time = stat($file)[8];
# OOPS, OUBLI DES PARENTHESES
# Trouver un chiffre hexadécimal.
$hexdigit = (’a’,’b’,’c’,’d’,’e’,’f’)[$digit-10];
# Un "opérateur virgule inversé".
return (pop(@foo),pop(@foo))[0];
Les listes ne peuvent être affectées que si chaque élément de la liste peut l’être lui aussi :
($a, $b, $c) = (1, 2, 3);
($map{’red’}, $map{’blue’}, $map{’green’}) = (0x00f, 0x0f0, 0xf00);
Une exception à ceci est que vous pouvez affecter undef dans une liste. C’est pratique pour balancer certaines valeurs de retour
d’une fonction :
($dev, $ino, undef, undef, $uid, $gid) = stat($file);
L’affectation de liste dans un contexte scalaire renvoit le nombre d’éléments produits par l’expression du côté droit de l’affectation :
$x = (($foo,$bar) = (3,2,1));
# met 3 dans $x, pas 2
$x = (($foo,$bar) = f());
# met le nombre de valeurs
# de retour de f() dans $x
Ceci est pratique lorsque vous voulez faire une affectation de liste dans un contexte booléen, parce que la plupart des fonctions de
liste renvoient une liste vide quand elle se terminent, ce qui donne un 0 quand on l’affecte, 0 qui est interprété comme FALSE (FAUX
- NDT).
L’élément ?nal peut être un tableau ou un hachage :
23

4.1. DESCRIPTION
perldata
($a, $b, @rest) = split;
local($a, $b, %rest) = @_;
Vous pouvez en vérité mettre un tableau ou un hachage n’importe où dans la liste, mais le premier situé dans la liste va aspirer toutes
les valeurs, et tout ce qui le suivra deviendra indé?ni. Cela peut être pratique dans un local() ou un my().
Un hachage peut être initialisé en utilisant une liste de littéraux contenant des paires d’éléments qui doivent être interprétées comme
des couples clé/valeur :
# identique à l’affectation de map ci-dessus
%map = (’red’,0x00f,’blue’,0x0f0,’green’,0xf00);
Tandis que les littéraux de liste et les tableaux nommés sont souvent interchangeables, ce n’est pas le cas pour les hachages. Le
simple fait que vous puissiez indicer une valeur de liste comme un tableau normal ne veut pas dire que vous pouvez indicer une
valeur de liste comme un hachage. De la même manière, les hachages inclus comme parties d’autres listes (y compris les listes de
paramètres et les listes de retour de fonctions) s’aplatissent toujours en paires clé/valeur. C’est pourquoi il est parfois bon d’utiliser
des références.
Il est parfois plus lisible d’utiliser l’opérateur => dans les paires clé/valeur. L’opérateur => est principalement juste un synonyme
plus clair visuellement qu’une virgule, mais il permet aussi à son opérande de gauche d’être interprété comme une chaîne, si c’est
un bareword qui serait un identi?ant légal. Cela rend plus jolie l’initialisation des hachages :
%map = (
red
=> 0x00f,
blue
=> 0x0f0,
green => 0xf00,
);
ou pour initialiser les références de hachage devant être utilisées en tant qu’enregistrements :
$rec = {
witch => ’Mable the Merciless’,
cat
=> ’Fluffy the Ferocious’,
date
=> ’10/31/1776’,
};
ou pour utiliser l’appel par variables pour les fonctions compliquées :
$field = $query->radio_group(
name
=> ’group_name’,
values
=> [’eenie’,’meenie’,’minie’],
default
=> ’meenie’,
linebreak => ’true’,
labels
=> \%labels
);
Notez que ce n’est pas parce qu’un hachage est initialisé dans un certain ordre qu’il ressortira dans cet ordre. Voir le titre sort dans
le manuel perlfunc pour des exemples sur la façon de s’arranger pour obtenir des sorties ordonnées.
4.1.6
Tranches
Une façon commune d’accéder à un tableau ou à un hachage est d’en prendre un élément à la fois. Vous pouvez aussi indicer une
liste pour en obtenir un seul élément.
$whoami = $ENV{"USER"};
# un élément du hachage
$parent = $ISA[0];
# un élément du tableau
$dir
= (getpwnam("daemon"))[7];
# idem, mais avec une liste
Une tranche accède à plusieurs éléments d’une liste, d’un tableau ou d’un hachage simultanément en utilisant une liste d’indices.
C’est plus pratique que d’écrire les éléments individuellement sous la forme d’une liste de valeurs scalaires séparées.
($him, $her)
= @folks[0,-1];
# tranche de tableau
@them
= @folks[0 .. 3];
# tranche de tableau
($who, $home)
= @ENV{"USER", "HOME"};
# tranche de hachage
($uid, $dir)
= (getpwnam("daemon"))[2,7];
# tranche de liste
24

4.1. DESCRIPTION
perldata
Puisque vous pouvez affecter à une liste de variables, vous pouvez aussi affecter à une tranche de tableau ou de hachage.
@days[3..5]
= qw/Wed Thu Fri/;
@colors{’red’,’blue’,’green’}
= (0xff0000, 0x0000ff, 0x00ff00);
@folks[0, -1]
= @folks[-1, 0];
Les affectations précédentes sont exactement équivalents à
($days[3], $days[4], $days[5]) = qw/Wed Thu Fri/;
($colors{’red’}, $colors{’blue’}, $colors{’green’})
= (0xff0000, 0x0000ff, 0x00ff00);
($folks[0], $folks[-1]) = ($folks[0], $folks[-1]);
Puisque changer une tranche change le tableau ou le hachage original dont la tranche est issue, une structure foreach altèrera
certaines – ou même toutes les – valeurs du tableau ou du hachage.
foreach (@array[ 4 .. 10 ]) { s/peter/paul/ }
foreach (@hash{keys %hash}) {
s/^\s+//;
# supprime les espaces au début des éléments
s/\s+$//;
# supprime les espaces à la fin des éléments
s/(\w+)/\u\L$1/g;
# met une majuscule aux mots
}
Une tranche d’une liste vide est encore une liste vide. Ainsi :
@a = ()[1,0];
# @a n’a pas d’éléments
@b = (@a)[0,1];
# @b n’a pas d’éléments
@c = (0,1)[2,3];
# @c n’a pas d’éléments
Mais :
@a = (1)[1,0];
# @a a deux éléments
@b = (1,undef)[1,0,2];
# @b a trois éléments
Ceci rend aisée l’écriture de boucles qui se terminent lorsqu’une liste nulle est renvoyée :
while ( ($home, $user) = (getpwent)[7,0]) {
printf "%-8s %s\n", $user, $home;
}
Comme noté précédemment dans ce document, le sens scalaire de l’affectation de liste est le nombre d’éléments de la partie droite
de l’affectation. La liste nulle ne contient pas d’éléments, donc lorsque le ?chier de mots de passes est vidé, le résultat est 0 et non
pas 2.
Si vous êtes troublé par le pourquoi de l’usage d’un ’@’ ici sur une tranche de hachage au lieu d’un ’%’, pensez-y ainsi. Le type
de parenthésage (avec des crochets ou des accolades) décide si c’est un tableau ou un hachage qui est examiné. D’un autre côté, le
symbole en pré?xe (’$’ ou ’@’) du tableau ou du hachage indique si vous récupérez une valeur simple (un scalaire) ou une valeur
multiple (une liste).
4.1.7
Typeglobs et Handles de Fichiers
Perl utilise un type interne appelé un typeglob pour contenir une entrée complète de table de symbole. Le pré?xe de type d’un
typeglob est une *, parce qu’il représente tous les types. Ceci fut la manière favorite de passer par référence à une fonction des
tableaux et des hachages, mais maintenant que nous avons de vraies références, c’est rarement nécessaire.
Le principal usage des typeglobs dans le Perl moderne est de créer des alias de table de symbole. Cette affectation :
*this = *that;
fait de $this un alias de $that, @this un alias de @that, %this un alias de %that, &this un alias de &that, etc. Il est bien plus sûr
d’utiliser une référence. Ceci :
local *Here::blue = \$There::green;
25

4.2. VOIR AUSSI
perldata
fait temporairement de $Here::blue un alias de $There::green, mais ne fait pas de @Hzere::blue un alias de @There::green, ou de
%Here::blue un alias de %There::green, etc. Voir le titre Tables de Symboles dans le manuel perlmod pour plus d’exemples de ceci.
Aussi étrange que cela puisse paraître, c’est la base de tout le système d’import/export de module.
Un autre usage des typeglobs est le passage de handles de ?chiers à une fonction, ou la création de nouveaux handles de ?chiers. Si
vous avez besoin d’utiliser un typeglob pour sauvegarder un handle de ?chier, faites-le de cette façon :
$fh = *STDOUT;
ou peut-être comme une vraie référence, comme ceci :
$fh = \*STDOUT;
Voir le manuel perlsub pour des exemples d’usages de ceci comme handles de ?chiers indirects dans des fonctions.
Les typeglobs sont aussi une façon de créer un handle de ?chier local en utilisant l’opérateur local(). Ceux-ci ne durent que jusqu’à
ce que leur bloc soit terminé, mais peuvent être passés en retour. Par exemple :
sub newopen {
my $path = shift;
local
*FH;
# not my!
open
(FH, $path) || return undef;
return *FH;
}
$fh = newopen(’/etc/passwd’);
Maintenant que nous avons la notation *foo{THING}, les typeglobs ne sont plus autant utilisés pour les manipulations de handles de
?chiers, même s’ils sont toujours nécessaires pour passer des ?chiers tout neufs et des handles de répertoire dans les fonctions. C’est
parce que *HANDLE{IO} ne fonctionne que si HANDLE a déjà été utilisé en tant que handle. En d’autres termes, *FH doit être utilisé
pour créer de nouvelles entrées de table de symboles ; *foo{THING} ne le peut pas. En cas de doute, utilisez *FH.
Toutes les fonctions qui sont capables de créer des handles de ?chiers (open(), opendir(), pipe(), socketpair(), sysopen(), socket(), et
accept()) créent automatiquement un handle de ?chier anonyme si le handle qui leur est passé est une variable scalaire non initialisée.
Ceci permet aux constructions telles que open(my $fh,  ) et open(local $fh, ) d’être utilisées pour créer des handles de
?chiers qui seront convenablement et automatiquement fermés lorsque la portée se termine, pourvu qu’il n’existe aucune autre
référence vers eux. Ceci élimine largement le besoin pour les typeglobs lors de l’ouverture des handles de ?chiers qui doivent être
passés à droite et à gauche, comme dans l’exemple suivant :
sub myopen {
open my $fh, "@_"
or die "Can’t open ’@_’: $!";
return $fh;
}
{
my $f = myopen("</etc/motd");
print <$f>;
# $f implicitly closed here
}
Une autre façon de créer des handles de ?chiers anonymes est d’utiliser le module Symbol ou le module IO::Handle et ceux de son
acabit. Ces modules ont l’avantage de ne pas cacher les différents types du même nom pendant le local(). Voir le bas de le titre open()
dans le manuel perlfunc pour un exemple.
4.2
VOIR AUSSI
Voir le manuel perlvar pour une description des variables intégrées de Perl et une discussion des noms de variable légaux. Voir le
manuel perlref, le manuel perlsub, et le titre Tables de Symboles dans le manuel perlmod pour plus de détails sur les typeglobs et la
syntaxe *foo{THING}.
4.3
VERSION FRANÇAISE
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.0. Pour en savoir plus concernant ces traductions,
consultez ;.
26

4.4. TRADUCTION
perldata
4.4
TRADUCTION
Roland Trique <>
4.5
RELECTURE
Jim Fox <>, Etienne Gauthier <>
27

Chapitre 5
perlop – Opérateurs Perl et priorité
Opérateurs Perl et priorité
5.1
SYNOPSIS
Le tableau suivant présente les opérateurs Perl et leur priorité, du plus prioritaire au moins prioritaire. Remarquez que tous les
opérateurs empruntés au C gardent le même ordre de priorité entre eux même lorsque ces priorités sont légèrement tordues. (Cela
rend plus simple l’apprentissage de Perl par les programmeurs C.) À quelques exceptions près, tous ces opérateurs agissent sur des
valeurs scalaires et pas sur des tableaux de valeurs.
gauche
termes et opérateurs de listes (leftward)
gauche
->
nonassoc
++ --
droite
**
droite
! ~ \ et + et - unaires
gauche
=~ !~
gauche
* / % x
gauche
+ - .
gauche
<< >>
nonassoc
opérateurs nommés unaires
nonassoc
< > <= >= lt gt le ge
nonassoc
== != <=> eq ne cmp
gauche
&
gauche
| ^
gauche
&&
gauche
||
nonassoc
..

droite
?:
droite
= += -= *= etc.
gauche
, =>
nonassoc
opérateurs de listes (rightward)
droite
not
gauche
and
gauche
or xor
Dans les sections qui suivent, ces opérateurs sont présentés par ordre de priorité.
De nombreux opérateurs peuvent être redé?nis pour des objets. Voir le manuel overload.
5.2
DESCRIPTION
5.2.1
Termes et opérateurs de listes (leftward)
Un TERME a la plus haute priorité en Perl. Cela inclut les variables, les apostrophes et autres opérateurs style apostrophe, les
expressions entre parenthèses et n’importe quelle fonction dont les arguments sont donnés entre parenthèses. En fait, ce ne sont pas
28

5.2. DESCRIPTION
perlop
vraiment des fonctions, juste des opérateurs de listes et des opérateurs unaires qui se comportent comme des fonctions parce que
vous avez mis des parenthèses autour des arguments. Tout cela est documenté dans le manuel perlfunc.
Si un opérateur de liste (print(), etc.) ou un opérateur unaire (chdir(), etc.) est directement suivi par une parenthèse gauche, l’opérateur
et les arguments entre parenthèses se voient attribués la priorité la plus haute exactement comme un appel de fonction.
En l’absence de parenthèses, la priorité des opérateurs de liste comme print, sort ou chmod n’est ni très haute ni très basse et
dépend de ce qu’il y a à gauche et/ou à droite de l’opérateur. Par exemple, dans :
@ary = (1, 3, sort 4, 2);
print @ary;
# affiche 1324
la virgule à droite du tri (sort) est évaluée avant le tri (sort) alors que la virgule de gauche est évaluée après. En d’autres termes, un
opérateur de listes a tendance à manger tous les arguments qui le suit et à se comporter comme un simple TERME par rapport à
l’expression qui le précède. Faites attention aux parenthèses :
# L’évaluation de exit a lieu avant le print !
print($foo, exit);
# Pas vraiment ce que vous vouliez.
print $foo, exit;
# Ni dans ce cas.
# L’évaluation de print a lieu avant le exit.
(print $foo), exit; # C’est ce que vous voulez.
print($foo), exit;
# Ici aussi.
print ($foo), exit; # Et encore dans ce cas.
Remarquez aussi que :
print ($foo & 255) + 1, "\n";
ne donne probablement pas ce que vous attendiez à priori. Voir les le titre Opérateurs unaires nommés dans ce document pour plus
de détails.
Sont aussi reconnus comme des termes les constructions do {} et eval {}, les appels à des subroutines ou à des méthodes ainsi
que les constructeurs anonymes [] et {}.
Voir aussi le titre Opérateurs apostrophe et type apostrophe dans ce document à la ?n de cette section mais aussi §5.2.29.
5.2.2
L’opérateur ?èche
Comme en C et en C++, "->" est un opérateur de déréférencement in?xe. Si du côté droit on trouve soit [ ], soit { }, soit
( ) alors le côté gauche doit être une référence vraie ou symbolique vers respectivement un tableau, une table de hachage ou une
subroutine (ou techniquement parlant, un emplacement capable de stocker une référence en dur si c’est une référence vers un tableau
ou une table de hachage utilisée pour une affectation). Voir le manuel perlreftut et le manuel perlref.
Par contre, si le côté droit est un nom de méthode ou une simple variable scalaire contenant un nom de méthode ou une référence
vers une subroutine alors le côté gauche doit être soit un objet (une référence bénie – par bless()) soit un nom de classe (c’est à dire
un nom de package). Voir le manuel perlobj.
5.2.3
Auto-incrémentation et Auto-décrémentation
"++" et "–" fonctionne comme en C. Placés avant la variable, ils incrémentent ou décrémentent la variable avant de retourner sa
valeur. Placés après, ils incrémentent ou décrémentent la variable après avoir retourner sa valeur.
De plus, l’opérateur d’auto-incrémentation inclut un comportement magique. Si vous incrémentez une variable numérique ou qui a
déjà été utilisée dans un contexte numérique, vous obtenez l’incrément normal. Si, par contre, la variable n’a été utilisée que dans
un contexte de chaîne et correspond au motif /ˆ[a-zA-Z]*[0-9]*$/, l’incrémentation a lieu sur la chaîne elle-même en préservant
les caractères dans leur intervalle et en gérant les éventuelles retenues :
print ++($foo = ’99’);
# affiche ’100’
print ++($foo = ’a0’);
# affiche ’a1’
print ++($foo = ’Az’);
# affiche ’Ba’
print ++($foo = ’zz’);
# affiche ’aaa’
L’opérateur d’auto-décrémentation n’est pas magique.
29

5.2. DESCRIPTION
perlop
5.2.4
Puissance
L’opérateur binaire "**" est l’opérateur puissance. Remarquez qu’il est plus prioritaire que le moins unaire donc -2**4 signi?e
-(2**4) et non pas (-2)**4. (Il est implémenté par la fonction C pow(3) qui travaille réellement sur des doubles en interne.)
5.2.5
Opérateurs symboliques unaires
L’opérateur unaire "!" est la négation logique, i.e. "non". Voir aussi not pour une version moins prioritaire de cet opération.
L’opérateur unaire "-" est la négation arithmétique si l’opérande est numérique. Si l’opérande est un identi?cateur, il retourne une
chaîne constituée du signe moins suivi de l’identi?cateur. Si la chaîne commence par un plus ou un moins, la valeur retournée est la
chaîne commençant par le signe opposé. L’un des effets de ces règles est que -bareword est équivalent à "-bareword".
L’opérateur unaire "˜" effectue la négation bit à bit, i.e. le complément à 1. Par exemple 0666 & ˜027 vaut 0640. (Voir aussi le
titre Arithmétique entière dans ce document et le titre Opérateurs bit à bit sur les chaînes dans ce document.) Notez que la taille du
résultat dépend de la plate-forme : ˜0 a une taille de 32 bits sur une plate-forme 32-bit et une taille de 64 bits sur une plate-forme
64-bit. Donc si vous attendez une certain nombre de bits, souvenez-vous d’utiliser l’opérateur & pour masquer les bits en excès.
L’opérateur unaire "+" n’a aucun effet même sur les chaînes. Il est pratique pour séparer syntaxiquement un nom de fonction d’une
expression entre parenthèses qui autrement aurait été interprétée comme la liste complète des arguments de la fonction. (Voir les
exemples de le titre Termes et opérateurs de listes (leftward) dans ce document.)
L’opérateur unaire "\" crée une référence vers ce qui le suit. Voir le manuel perlref. Ne confondez pas ce comportement avec celui
de la barre oblique inversée (backslash) à l’intérieur d’une chaîne bien que les deux formes proposent une sorte de protection contre
l’interprétation de ce qui les suit.
5.2.6
Opérateurs d’application d’expressions rationnelles
L’opérateur binaire "=˜" applique un motif de reconnaissance à une expression scalaire. Plusieurs opérations cherchent ou modi?ent
la chaîne $_ par défaut. Cet opérateur permet d’appliquer cette sorte d’opérations à d’autres chaînes. L’argument de droite est le
motif de recherche, de substitution ou de remplacement. L’argument de gauche est ce qui est supposé être cherché, substitué ou
remplacé à la place de la valeur par défaut $_. Dans un contexte scalaire, la valeur retournée indique généralement le succès de
l’opération. Le comportement dans un contexte de liste dépend de chaque opérateur. Voir §5.2.26.
Si l’argument de droite est une expression plutôt qu’un motif de recherche, de substitution ou de remplacement, il est interprété
comme un motif de recherche lors de l’exécution. Cela peut être moins ef?cace qu’une recherche explicite puisque le motif doit être
compilé à chaque fois que l’expression est évaluée.
L’opérateur binaire "!˜" est exactement comme "=˜" sauf que la valeur retournée est le contraire au sens logique.
5.2.7
Opérateurs type multiplication
L’opérateur binaire "*" multiplie deux nombres.
L’opérateur binaire "/" divise deux nombres.
L’opérateur binaire "%" calcule le modulo de deux nombres. Soit deux opérandes entiers donnés $a et $b : si $b est positif alors $a
% $b vaut $a moins le plus grand multiple de $b qui n’est pas plus grand que $a. Si $b est négatif alors $a % $b vaut $a moins le
plus petit multiple de $b qui n’est pas plus petit que $a (i.e. le résultat est plus petit ou égal à zéro). Remarquez que lorsque vous êtes
dans la portée de use integer, "%" vous donne accès directement à l’opérateur modulo tel qu’il est dé?ni par votre compilateur C.
Cet opérateur n’est pas très bien dé?ni pour des opérandes négatifs mais il s’exécute plus rapidement.
L’opérateur binaire "x" est l’opérateur de répétition. Dans un contexte scalaire, il retourne une chaîne constituée de son opérande
de gauche répété le nombre de fois spéci?é par son opérande de droite. Dans un contexte de liste, si l’opérande de gauche est entre
parenthèses, il répète la liste.
print ’-’ x 80;
# affiche une ligne de ’-’
print "\t" x ($tab/8), ’ ’ x ($tab%8);
# tab over
@ones = (1) x 80;
# une liste de quatre-vingt 1.
@ones = (5) x @ones;
# place tous les éléments à 5.
30

5.2. DESCRIPTION
perlop
5.2.8
Opérateurs type addition
L’opérateur binaire "+" retourne la somme de deux nombres.
L’opérateur binaire "-" retourne la différence de deux nombres.
L’opérateur binaire "." concatène deux chaînes.
5.2.9
Opérateurs de décalages
L’opérateur binaire "«" retourne la valeur de son opérande de gauche décalée vers la gauche d’un nombre de bits spéci?é par son
opérande de droite. Les arguments devraient être des entiers. (Voir aussi le titre Arithmétique entière dans ce document.)
L’opérateur binaire "»" retourne la valeur de son opérande de gauche décalée vers la droite d’un nombre de bits spéci?é par son
opérande de droite. Les arguments devraient être des entiers. (Voir aussi le titre Arithmétique entière dans ce document.)
5.2.10
Opérateurs unaires nommés
Les différents opérateurs unaire nommés sont traités comme des fonctions à un argument avec des parenthèses optionnelles. Ceci
inclut les opérateurs de tests de ?chiers comme -f, -M, etc. Voir le manuel perlfunc.
Si un opérateur de liste (print(), etc.) ou un opérateur unaire (chdir(), etc.) est suivi d’une parenthèse ouvrante, l’opérateur et ses
arguments entre parenthèses sont considérés comme de priorité la plus haute exactement comme n’importe quel appel à une fonction.
Exemples :
chdir $foo
|| die;
# (chdir $foo) || die
chdir($foo)
|| die;
# (chdir $foo) || die
chdir ($foo)
|| die;
# (chdir $foo) || die
chdir +($foo) || die;
# (chdir $foo) || die
mais puisque * est plus prioritaire que || :
chdir $foo * 20;
# chdir ($foo * 20)
chdir($foo) * 20;
# (chdir $foo) * 20
chdir ($foo) * 20;
# (chdir $foo) * 20
chdir +($foo) * 20; # chdir ($foo * 20)
rand 10 * 20;
# rand (10 * 20)
rand(10) * 20;
# (rand 10) * 20
rand (10) * 20;
# (rand 10) * 20
rand +(10) * 20;
# rand (10 * 20)
Voir aussi §5.2.1.
5.2.11
Opérateurs de comparaisons
L’opérateur binaire "<" renvoie vrai si son opérande gauche est numériquement plus petit que son opérande droit.
L’opérateur binaire ">" renvoie vrai si son opérande gauche est numériquement plus grand que son opérande droit.
L’opérateur binaire "<=" renvoie vrai si son opérande gauche est numériquement plus petit ou égal que son opérande droit.
L’opérateur binaire ">=" renvoie vrai si son opérande gauche est numériquement plus grand ou égal que son opérande droit.
L’opérateur binaire "lt" renvoie vrai si son opérande gauche est alphabétiquement plus petit que son opérande droit.
L’opérateur binaire "gt" renvoie vrai si son opérande gauche est alphabétiquement plus grand que son opérande droit.
L’opérateur binaire "le" renvoie vrai si son opérande gauche est alphabétiquement plus petit ou égal que son opérande droit.
L’opérateur binaire "ge" renvoie vrai si son opérande gauche est alphabétiquement plus grand ou égal que son opérande droit.
31

5.2. DESCRIPTION
perlop
5.2.12
Opérateurs d’égalité
L’opérateur binaire "==" renvoie vrai si l’opérande gauche est numériquement égal à l’opérande droit.
L’opérateur binaire "!=" renvoie vrai si l’opérande gauche n’est pas numériquement égal à l’opérande droit.
L’opérateur binaire "<=>" renvoie -1, 0 ou 1 selon que l’opérande gauche est numériquement et respectivement plus petit, égal ou
plus grand que l’opérande droit.
L’opérateur binaire "eq" renvoie vrai si l’opérande gauche est égal alphabétiquement à l’opérande droit.
L’opérateur binaire "ne" renvoie vrai si l’opérande gauche n’est pas égal alphabétiquement à l’opérande droit.
L’opérateur binaire "cmp" renvoie -1, 0 ou 1 selon que l’opérande gauche est alphabétiquement et respectivement plus petit, égal ou
plus grand que l’opérande droit.
"lt", "le", "ge", "gt" et "cmp" utilise l’ordre de tri (collation) spéci?é par le locale courant si use locale est actif. Voir le manuel
perllocale.
5.2.13
Opérateur Et bit à bit
L’opérateur binaire "&" renvoie le résultat d’un ET bit à bit entre ses opérandes. (Voir aussi le titre Arithmétique entière dans ce
document et le titre Opérateurs bit à bit sur les chaînes dans ce document.)
5.2.14
Opérateurs Ou et Ou exclusif bit à bit
L’opérateur binaire "|" renvoie le résultat d’un OU bit à bit entre ses deux opérandes. (Voir aussi le titre Arithmétique entière dans ce
document et le titre Opérateurs bit à bit sur les chaînes dans ce document.)
L’opérateur binaire "ˆ" renvoie le résultat d’un OU EXCLUSIF (XOR) bit à bit entre ses deux opérandes. (Voir aussi le titre Arith-
métique entière dans ce document et le titre Opérateurs bit à bit sur les chaînes dans ce document.)
5.2.15
Et logique style C
L’opérateur binaire "&&" calcule un ET logique rapide. Cela signi?e que si l’opérande gauche est faux, l’opérande droit n’est même
pas évalué. Le contexte scalaire ou de liste se propage vers l’opérande droit si il est évalué.
5.2.16
Ou logique style C
L’opérateur binaire "||" calcule un OU logique rapide. Cela signi?e que si l’opérande gauche est vrai, l’opérande droit n’est même
pas évalué. Le contexte scalaire ou de liste se propage vers l’opérande droit si il est évalué.
Les opérateurs || et && diffèrent du C sur un point : au lieu de renvoyer 0 ou 1, ils renvoient la dernière valeur évaluée. Donc, un
moyen raisonnablement portable de trouver le répertoire home (en supposant que ce ne soit pas "0") peut être :
$home = $ENV{’HOME’} || $ENV{’LOGDIR’} ||
(getpwuid($<))[7] || die "You’re homeless!\n";
En particulier, cela signi?e que vous ne devriez pas les utiliser pour choisir entre deux agrégats dans une <affectation :>
@a = @b || @c;
# c’est pas bon
@a = scalar(@b) || @c;
# voila ce que ça signifie
@a = @b ? @b : @c;
# cela marche très bien par contre
Pour remplacer d’une manière plus lisible l’usage de && et || pour contrôler un ?ot d’opérations, Perl propose les opérateurs and et
or (voir plus bas). Le comportement d’évaluation rapide est le même. Par contre, la priorité de "and" et "or" est plus basse, vous
pouvez donc les utiliser après les opérateurs de listes sans ajouter de parenthèses :
unlink "alpha", "beta", "gamma"
or gripe(), next LINE;
Avec les opérateurs à la C, vous auriez dû l’écrire :
unlink("alpha", "beta", "gamma")
|| (gripe(), next LINE);
En revanche, l’utilisation de "or" lors d’une affectation ne donne pas ce que vous voulez; voir plus bas.
32

5.2. DESCRIPTION
perlop
5.2.17
Opérateurs d’intervalle
L’opérateur binaire ".." est l’opérateur d’intervalle qui est en fait deux opérateurs totalement différents selon le contexte. Dans un
contexte de liste, il renvoie un tableau de valeurs commençant à la valeur de son opérande gauche et se terminant à la valeur de son
opérande droit (par pas de 1). Si la valeur de gauche est plus petite que la valeur de droite, il retourne un tableau vide. C’est pratique
pour écrire des boucles foreach (1..10) et pour des opérations de remplacement sur des tableaux. Dans l’implémentation actuelle,
aucun tableau temporaire n’est généré lorsque l’opérateur d’intervalle est utilisé comme expression de boucles foreach mais les
vieilles versions de Perl peuvent consommer énormément de mémoire lorsque vous écrivez quelque chose comme :
for (1 .. 1_000_000) {
# code
}
Dans un contexte scalaire, ".." renvoie une valeur booléenne. L’opérateur est bi-stable comme un interrupteur et simule l’opérateur
d’intervalle de ligne (virgule) de sed, de awk et d’autres éditeurs. Chaque opérateur ".." conserve en mémoire son propre état
booléen. Il reste faux tant que son opérande gauche est faux. Puis dès que son opérande gauche devient vrai, il reste vrai jusqu’à ce
que son opérande droit soit vrai. APRÈS quoi, l’opérateur d’intervalle redevient faux. Il ne redevient faux que le prochaine fois que
l’opérateur d’intervalle est évalué. Il peut tester l’opérande droit et devenir faux lors de la même évaluation où il devient vrai (comme
dans awk) mais il retournera encore une fois vrai. Si vous ne voulez pas qu’il teste l’opérande droit avant la prochaine évaluation
(comme dans sed), utilisez trois points (" ") à la place de deux. Pour tout le reste, " " se comporte exactement comme "..".
L’opérande droit n’est pas évalué tant que l’opérateur est dans l’état "faux" et l’opérande gauche n’est pas évalué tant que l’opérateur
est dans l’état "vrai". La priorité de l’opérateur intervalle est un peu plus basse que celle de || et &&. La valeur retournée est soit
la chaîne vide pour signi?er "faux" soit un numéro de séquence (commençant à 1) pour "vrai". Le dernier numéro de séquence
d’un intervalle est suivi de la chaîne "E0" ce qui ne perturbe pas sa valeur numérique mais vous donne quelque chose à chercher si
vous voulez exclure cette dernière valeur. Vous pouvez exclure la première valeur en demandant une valeur supérieure à 1. Si l’un
des opérandes de l’opérateur intervalle pris dans un contexte scalaire est une expression constante, cette opérande est implicitement
comparé à la variable $. (le numéro de ligne courant). Exemples :
Comme opérateur scalaire :
if (101 .. 200) { print; }
# affiche la seconde centaine de lignes
next line if (1 .. /^$/);
# saut des lignes d’en-têtes
s/^/> / if (/^$/ .. eof()); # place le corps comme citation
# analyse d’e-mail
while (<>) {
$in_header =
1
.. /^$/;
$in_body
= /^$/ .. eof();
# faire quelque chose avec
} continue {
close ARGV if eof;
# réinitialisation de $. à chaque fichier
}
Comme opérateur de liste :
for (101 .. 200) { print; } # affiche $_ 100 fois
@foo = @foo[0 .. $#foo];
# un no-op coûteux
@foo = @foo[$#foo-4 .. $#foo];
# extraction des 5 derniers items
L’opérateur intervalle (dans un contexte de liste) utilise l’algorithme magique d’auto-incrémentation si les opérandes sont des
chaînes. Vous pouvez écrire :
@alphabet = (’A’ .. ’Z’);
pour obtenir toutes les lettres de l’alphabet ou
$hexdigit = (0 .. 9, ’a’ .. ’f’)[$num & 15];
pour obtenir les chiffres hexadécimaux ou
@z2 = (’01’ .. ’31’);
print $z2[$mjour];
pour obtenir des dates avec des zéros. Si la valeur ?nale donnée n’est pas dans la séquence produite par l’incrémentation magique,
la séquence continue jusqu’à ce que la prochaine valeur soit plus longue que la valeur ?nale spéci?ée.
33

5.2. DESCRIPTION
perlop
5.2.18
L’opérateur conditionnel
L’opérateur "?:" est l’opérateur conditionnel exactement comme en C. Il travaille presque comme un si-alors-sinon. Si l’argument
avant le ? est vrai, l’argument avant le : est renvoyé sinon l’argument après le : est renvoyé. Par exemple :
printf "J’ai %d chien%s.\n", $n,
($n == 1) ? ’’ : "s";
Le contexte scalaire ou de liste se propage au second ou au troisième argument quelque soit le choix.
$a = $ok ? $b : $c;
# un scalaire
@a = $ok ? @b : @c;
# un tableau
$a = $ok ? @b : @c;
# oups, juste un compte !
On peut affecter quelque chose à l’opérateur si le second ET le troisième arguments sont des lvalues légales (ce qui signi?e qu’on
peut leur affecter quelque chose) :
($a_or_b ? $a : $b) = $c;
Il n’y a aucune garantie que cela contribue à la lisibilité de votre programme.
Puisque l’opérateur produit un résultat affectable, l’usage d’affectation sans parenthèse peut amener quelques problèmes. Par
exemple, le ligne suivante :
$a % 2 ? $a += 10 : $a += 2
signi?e réellement :
(($a % 2) ? ($a += 10) : $a) += 2
au lieu de :
($a % 2) ? ($a += 10) : ($a += 2)
Cela aurait probablement pu être écrit plus simplement :
$a += ($a % 2) ? 10 : 2;
5.2.19
Opérateurs d’affectation
"=" est l’opérateur habituel d’affectation.
Les opérateurs d’affectation fonctionnent comme en C. Donc :
$a += 2;
est équivalent à :
$a = $a + 2;
quoique sans dupliquer les éventuels effets de bord que le déréférencement de la lvalue pourraient déclencher, comme par exemple
avec tie(). Les autres opérateurs d’affectation fonctionnent de la même manière. Voici ceux qui sont reconnus :
**=
+=
*=
&=
<<=
&&=
-=
/=
|=
>>=
||=
.=
%=
^=
x=
Remarque: bien que regroupés par famille, tous ces opérateurs ont la même priorité que l’affectation.
Au contraire du C, les opérateurs d’affectation produisent une lvalue valide. Modi?er une affectation est équivalent à faire l’affec-
tation puis à modi?er la variable qui vient d’être affectée. C’est très pratique pour modi?er une copie de quelque chose comme
dans :
($tmp = $global) =~ tr [A-Z] [a-z];
De même :
($a += 2) *= 3;
est équivalent à :
$a += 2;
$a *= 3;
De manière similaire, une affectation vers une liste dans un contexte de liste produit la liste des lvalues affectées et dans un contexte
scalaire produit le nombre d’éléments présents dans l’opérande de droite de l’affectation.
34

5.2. DESCRIPTION
perlop
5.2.20
Opérateur virgule
L’opérateur binaire "," est l’opérateur virgule. Dans un contexte scalaire, il évalue son opérande gauche et jette le résultat puis il
évalue son opérande droit et retourne cette valeur. C’est exactement comme l’opérateur virgule du C.
Dans un contexte de liste, c’est tout simplement le séparateur d’arguments de la liste. Il insère ses deux opérandes dans la liste.
Le digramme => est un synonyme de l’opérateur virgule. C’est pratique pour indiquer que les arguments fonctionnent par paires.
Depuis la version 5.001, il contraint le mot à sa gauche à être interprété comme une chaîne.
5.2.21
Opérateurs de listes (Rightward)
Du côté droit d’un opérateur de liste, il a une priorité très basse qui permet de maîtriser toutes les expressions présentes séparées par
des virgules. Les seuls opérateurs de priorité inférieure sont les opérateurs logiques "and", "or" et "not" qui peuvent être utiliser pour
évaluer plusieurs appels à des opérateurs de liste sans l’ajout de parenthèses supplémentaires :
open HANDLE, "filename"
or die "Can’t open: $!\n";
Voir aussi la discussion sur les opérateurs de liste dans le titre Termes et opérateurs de liste (leftward) dans ce document.
5.2.22
Non (not) logique
L’opérateur unaire "not" renvoie la négation logique de l’expression à sa droite. Il est équivalent à "!" sauf sa priorité beaucoup plus
basse.
5.2.23
Et (et) logique
L’opérateur binaire "and" renvoie la conjonction logique des deux expressions qui l’entourent. Il est équivalent à && sauf sa priorité
beaucoup plus basse. Cela signi?e qu’il est rapide: i.e., l’expression de droite est évaluée uniquement si celle de gauche est vraie.
5.2.24
Ou (or) et ou exclusif (xor) logique
L’opérateur binaire "or" renvoie la disjonction logique des deux expressions qui l’entourent. Il est équivalent à || sauf sa priorité
beaucoup plus basse. C’est pratique pour contrôler une suite d’opérations :
print FH $data
or die "Can’t write to FH: $!";
Cela signi?e qu’il est rapide: i.e., l’expression de droite est évaluée uniquement si celle de gauche est fausse. À cause de sa priorité,
vous devriez l’éviter dans les affectations et ne l’utiliser que pour du contrôle d’opérations.
$a = $b or $c;
# bug: c’est pas bon
($a = $b) or $c;
# voila ce que ça signifie
$a = $b || $c;
# il vaut mieux l’écrire ainsi
Au contraire, lorsque l’affectation est dans un contexte de liste et que vous voulez utiliser "||" pour du contrôle, il vaut mieux utiliser
"or" pour que l’affectation soit prioritaire.
@info = stat($file) || die;
# holà, sens scalaire de stat !
@info = stat($file) or die;
# meilleur, @info reçoit ce qu’il faut
Bien sûr, il est toujours possible d’utiliser les parenthèses.
L’opérateur binaire "xor" renvoie le ou exclusif des deux expressions qui l’entourent. Il ne peut évidemment pas être rapide.
5.2.25
Opérateurs C manquant en Perl
Voici ce qui existe en C et que Perl n’a pas :
& unaire
Opérateur adresse-de. (Voir l’opérateur "\" pour prendre une référence.)
* unaire
Opérateur contenu-de ou de déréférencement. (Les opérateurs de déréférencement de Perl sont des pré?xes typés : $, @, % et
&.)
(TYPE)
Opérateur de conversion de type (de cast).
35

5.2. DESCRIPTION
perlop
5.2.26
Opérateurs apostrophe et type apostrophe
Bien qu’habituellement nous pensions aux apostrophes (et autres guillemets) pour des valeurs littérales, en Perl, elles fonctionnent
comme des opérateurs et proposent différents types d’interpolation et de capacités de reconnaissance de motif. Perl fournit des
caractères standard pour cela mais fournit aussi le moyen de choisir vos propres caractères. Dans la table suivante, le {} représente
n’importe quelle paire de délimiteurs que vous aurez choisie.
Standard
Générique
Signification
Interpolation
’’
q{}
Littérale
non
""
qq{}
Littérale
oui
‘‘
qx{}
Commande
oui (sauf si délimiteur ’’)
qw{}
Liste de mots
non
//
m{}
Reconnaissance de motif
oui (sauf si délimiteur ’’)
qr{}
Motif
oui (sauf si délimiteur ’’)
s{}{}
Substitution
oui (sauf si délimiteur ’’)
tr{}{}
Translittération
non (voir plus bas)
Les délimiteurs qui ne marchent pas par deux utilisent le même caractère au début et à la ?n par contre les quatre sortes de parenthèses
(parenthèses, crochets, accolades et inférieur/supérieur) marchent par deux et peuvent être imbriquées ce qui signi?e que :
q{foo{bar}baz}
est la même chose que :
’foo{bar}baz’
Remarquez par contre que cela ne fonctionne pas toujours. Par exemple :
$s = q{ if($a eq "}")   }; # Mauvais
est une erreur de syntaxe. Le module Text::Balanced disponible sur CPAN est capable de gérer cela correctement.
Il peut y avoir des espace entre l’opérateur et le caractère délimiteur sauf lorsque # est utilisé. q#foo# est interprété comme la chaîne
foo alors que q #foo# est l’opérateur q suivi d’un commentaire. Ses arguments sont alors pris sur la ligne suivante. Cela permet
d’écrire :
s {foo}
# Remplace foo
{bar}
# par bar.
Pour les constructions qui réalisent une interpolation, les variables commençant par "$" ou "@" sont interpolées ainsi que les sé-
quences suivantes. Dans une translittération, seules les douze premières séquences sont utilisables.
\t
tabulation
(HT, TAB)
\n
nouvelle ligne
(LF, NL)
\r
retour chariot
(CR)
\f
page suivante
(FF)
\a
alarme (bip)
(BEL)
\e
escape
(ESC)
\033
caractère en octal
(ESC)
\x1B
caractère hexadécimal
(ESC)
\x{236a}
caractère hexadécimal long (SMILEY)
\c[
caractère de contrôle
(ESC)
\N{nom}
caractère nommé
\l
converti en minuscule le caractère suivant
\u
converti en majuscule le caractère suivant
\L
converti en minuscule jusqu’au prochain \E
\U
converti en majuscule jusqu’au prochain \E
\E
fin de modification de casse
\Q
désactive les méta-caractères de motif jusqu’au prochain \E
36

5.2. DESCRIPTION
perlop
Si use locale est actif, la table de majuscules/minuscules utilisée par \l, \L, \u et \U est celle du locale courant. Voir le manuel
perllocale. Pour la documentation de \N{nom}, voir le manuel charnames.
Tous les systèmes utilisent le "\n" virtuel pour représenter une terminaison de ligne appelée "newline" ou "nouvelle ligne". Il
n’existe pas de caractère physique invariant pour représenter ce caractère "newline". C’est une illusion qu’essayent conjointement
de maintenir le système d’exploitation, les pilotes de périphériques, la bibliothèque C et Perl. Tous les systèmes ne lisent pas "\r"
comme le CR ASCII ni "\n" comme le LF ASCII. Par exemple, sur Mac, ils sont inversés et sur des systèmes sans terminaison
de ligne, écrire "\n" peut ne produire aucun donnée. En général, utilisez "\n" lorsque vous pensez "newline" pour votre système
mais utilisez le littéral ASCII quand voulez un caractère exact. Par exemple, de nombreux protocoles réseaux attendent et préfèrent
un CR+LF (("\012\015" ou "\cJ\cM") comme terminaison de ligne. La plupart acceptent juste "\012" et tolère rarement juste
"\015". Si vous prenez l’habitude d’utiliser "\n" sur les réseaux, vous aurez des problèmes un jour.
Vous ne pouvez pas inclure littéralement les caractères $ et @ à l’intérieur d’une séquence \Q. Tels quels, ils se référeraient à la
variable correspondante. Précédés d’un \, ils correspondraient à la chaîne \$ ou \@. Vous êtes obligés d’écrire quelque chose comme
m/\Quser\E\@\Qhost/.
Les motifs sont sujets à un niveau supplémentaire d’interprétation en tant qu’expression rationnelle. C’est fait lors d’une seconde
passe après l’interpolation des variables si bien qu’une expression rationnelle peut-être introduite dans un motif via une variable. Si
ce n’est pas ce que vous voulez, utilisez \Q pour interpoler une variable littéralement.
Mis à part ce qui précède, il n’y pas de multiples niveaux d’interpolation. En particulier et contrairement à ce qu’attendraient
des programmeurs shell, les accents graves (ou backticks) NE sont PAS interpolées à l’intérieur des guillemets et les apostrophes
n’empêchent pas l’évaluation des variables à l’intérieur des guillemets.
5.2.27
Opérateurs d’expression rationnelle
Nous discuterons ici des opérateurs style apostrophe qui implique une reconnaissance de motif ou une action s’y rapportant.
?MOTIF?
C’est la même chose qu’une recherche par /motif/ sauf qu’elle n’est reconnue qu’une seule fois entre chaque appel à l’opé-
rateur reset(). C’est une optimisation pratique si vous ne recherchez que la première occurrence de quelque chose dans chaque
?chier ou groupes de ?chiers par exemple. Seuls les motifs ?? locaux au package courant sont réinitialisés par reset().
while (<>) {
if (?^$?) {
# ligne blanche entre en-tête et corps
}
} continue {
reset if eof;
# réinitialisation de ?? pour le fichier suivant
}
Cet usage est vaguement désapprouvé et peut être supprimé dans une version future de Perl. Peut-être vers l’année 2168.
m/MOTIF/cgimosx
/MOTIF/cgimosx
Effectue le recherche d’un motif d’expression rationnelle dans une chaîne et, dans un contexte scalaire, renvoie vrai en cas
de succès ou faux sinon. Si aucune chaîne n’est spéci?ée via l’opérateur =˜ ou l’opérateur !˜, c’est dans la chaîne $_ que
s’effectue la recherche. (La chaîne spéci?ée par =˜ n’est pas nécessairement une lvalue – cela peut être le résultat de l’éva-
luation d’une expression.) Voir aussi le manuel perlre. Voir le manuel perllocale pour des informations supplémentaires qui
s’appliquent lors de l’usage de use locale.
Les options (ou modi?cateurs) sont :
c
Ne pas réinitialiser la position de recherche lors d’un échec avec /g.
g
Recherche globale, i.e. trouver toutes les occurrences.
i
Reconnaissance de motif indépendamment de la casse (majuscules/minuscules).
m
Traitement de chaîne comme étant multi-lignes.
o
Compilation du motif uniquement la première fois.
s
Traitement de la chaîne comme étant une seule ligne.
x
Utilisation des expressions rationnelles étendues.
Si "/" est le délimiteur alors le m initial est optionnel. Avec le m vous pouvez utiliser n’importe quelle paire de caractères ni
alphanumériques ni blancs comme délimiteur. C’est particulièrement pratique pour les chemins d’accès Unix qui contiennent
des "/" a?n d’éviter le LTS (leaning toothpick syndrome). Si "?" est le délimiteur alors la règle "ne-marche-qu-une-fois"
de ?MOTIF? s’applique. Si "’" est le délimiteur alors aucune interpolation n’est effectuée sur le MOTIF.
37

5.2. DESCRIPTION
perlop
MOTIF peut contenir des variables qui seront interpolées (et le motif recompilé) chaque fois que la recherche du motif est
effectuée sauf si le délimiteur choisi est une apostrophe. (Remarquez que $) et $| ne peuvent pas être interpolés puisqu’ils
ressemblent à des tests de ?n de chaîne.) Si vous voulez qu’un motif ne soit compilé qu’une seule fois, ajoutez /o après le
dernier délimiteur. Ceci évite des coûteuses recompilations lors de l’exécution et c’est utile lorsque le valeur interpolée ne doit
pas changer pendant la durée de vie du script. Par contre, ajouter /o suppose que vous ne changerez pas la valeur des variables
présentes dans le motif. Si vous les changez, Perl ne s’en apercevra même pas. Voir aussi §??.
Si l’évaluation du MOTIF est la chaîne vide, la dernière expression rationnelle reconnue est utilisée à la place.
Si l’option /g n’est pas utilisée, dans un contexte de liste, m// retourne une liste constituée de tous les sous-motifs reconnus
par des parenthèses dans le motif, i.e. ($1, $2, $3 ). (Remarquez que $1, $2, etc. sont aussi mises à jours ce qui diffère du
comportement de Perl 4.) Lorsqu’il n’y a pas de parenthèses dans le motif, la valeur retournée est la liste (1) en cas de succès.
Qu’il y ait ou non de parenthèses, une liste vide est retournée en cas d’échec.
Exemples :
open(TTY, ’/dev/tty’);
<TTY> =~ /^y/i && foo();
# appel de foo si désiré
if (/Version: *([0-9.]*)/) { $version = $1; }
next if m#^/usr/spool/uucp#;
# le grep du pauvre
$arg = shift;
while (<>) {
print if /$arg/o;
# compile une seule fois
}
if (($F1, $F2, $Etc) = ($foo =~ /^(\S+)\s+(\S+)\s*(.*)/))
Ce dernier exemple découpe $foo en trois parties (le deux premiers mots et le reste de la ligne) et les affecte à $F1, $F2 et
$Etc. La condition est vraie si au moins une des variables est affectée, i.e. si le motif est reconnu.
Le modi?cateur /g spéci?e une recherche globale du motif – c’est à dire la recherche d’autant de correspondances que
possible dans la chaîne. Le comportement dépend du contexte. Dans un contexte de liste, c’est la liste de toutes les sous-
chaînes reconnues par les sous-motifs (entre parenthèses) du motif qui est retournée. En l’absence de parenthèses, c’est la liste
de toutes les chaînes correspondant au motif qui est retournée, comme si il y avait des parenthèses autour du motif lui-même.
Dans un contexte scalaire, chaque exécution de m//g trouve la prochaine correspondance et retourne vrai si il y a correspon-
dance et faux si il n’y en a plus. La position après la dernière correspondance peut-être lue et modi?ée par la fonction pos();
voir le titre pos dans le manuel perlfunc. Normalement, un échec de la recherche réinitialise la position de recherche au début
de la chaîne sauf si vous ajoutez le modi?cateur /c (e.g. m//gc). La modi?cation de la chaîne sur laquelle à lieu la recherche
réinitialise aussi la position de recherche.
Vous pouvez mélanger des reconnaissances m//g avec des m/\G /g où \G est l’assertion de longueur nulle qui est reconnue
à la position exacte où, si elle existe, s’est arrêtée la précédente recherche m//g. L’assertion \G n’est pas acceptable sans le
modi?cateur /g. (Dans la version courante, en l’absence de /g, il se trouve que \G se comporte exactement comme \A mais
c’est accidentel et cela peut changer dans les versions futures.)
Exemples :
# contexte de liste
($one,$five,$fifteen) = (‘uptime‘ =~ /(\d+\.\d+)/g);
# contexte scalaire
{
local $/ = "";
while (defined($paragraph = <>)) {
while ($paragraph =~ /[a-z][’")]*[.!?]+[’")]*\s/g) {
$sentences++;
}
}
}
print "$sentences\n";
# utilisation de m//gc avec \G
$_ = "ppooqppqq";
while ($i++ < 2) {
print "1: ’";
38

5.2. DESCRIPTION
perlop
print $1 while /(o)/gc; print "’, pos=", pos, "\n";
print "2: ’";
print $1 if /\G(q)/gc;
print "’, pos=", pos, "\n";
print "3: ’";
print $1 while /(p)/gc; print "’, pos=", pos, "\n";
}
Le dernier exemple devrait af?cher :
1: ’oo’, pos=4
2: ’q’, pos=5
3: ’pp’, pos=7
1: ’’, pos=7
2: ’q’, pos=8
3: ’’, pos=8
Une construction idiomatique pratique pour des analyseurs à la lex est /\G /gc. Vous pouvez combiner plusieurs expres-
sions rationnelles de ce type pour traiter une chaîne partie par partie en faisant différentes actions selon l’expression qui est
reconnue. Chaque expression essaye de correspondre là où la précédente s’est arrêtée.
$_ = <<’EOL’;
$url = new URI::URL "http://www/";
die if $url eq "xXx";
EOL
LOOP:
{
print(" chiffres"),
redo LOOP if /\G\d+\b[,.;]?\s*/gc;
print(" minuscule"),
redo LOOP if /\G[a-z]+\b[,.;]?\s*/gc;
print(" MAJUSCULE"),
redo LOOP if /\G[A-Z]+\b[,.;]?\s*/gc;
print(" Capitalisé"),
redo LOOP if /\G[A-Z][a-z]+\b[,.;]?\s*/gc;
print(" MiXtE"),
redo LOOP if /\G[A-Za-z]+\b[,.;]?\s*/gc;
print(" alphanumérique"), redo LOOP if /\G[A-Za-z0-9]+\b[,.;]?\s*/gc;
print(" autres"),
redo LOOP if /\G[^A-Za-z0-9]+/gc;
print ". C’est tout !\n";
}
Voici la sortie (découpée en plusieurs lignes) :
autres minuscule autres minuscule MAJUSCULE autres
MAJUSCULE autres minuscule autres minuscule autres
minuscule minuscule autres minuscule minuscule autres
MiXtE autres. C’est tout !
q/CHAINE/
’CHAINE’
Une apostrophe pour une chaîne littérale. Un backslash (une barre oblique inverse) représente un backslash sauf si il est suivi
par le délimiteur ou par un autre backslash auquel cas le délimiteur ou le backslash est interpolé.
$foo = q!I said, "You said, ’She said it.’"!;
$bar = q(’This is it.’);
$baz = ’\n’;
# une chaîne de deux caractères
qq/CHAINE/
"CHAINE"
Des guillemets pour une chaîne interpolée.
$_ .= qq
(*** La ligne précédente contient le gros mot "$1".\n)
if /\b(tcl|java|python)\b/i;
# :-)
$baz = "\n";
# une chaîne d’un caractère
qr/CHAINE/imosx
Opérateur "comme-une-expression-regulière". CHAINE est interpolée de la même manière que MOTIF dans m/MOTIF/. Si
"’" est utilisé comme délimiteur, aucune interpolation de variables n’est effectuée. Renvoie une expression Perl qui peut être
utilisée à la place de l’expression /CHAINE/imosx.
Par exemple :
39

5.2. DESCRIPTION
perlop
$rex = qr/ma.CHAINE/is;
s/$rex/foo/;
est équivalent à :
s/ma.CHAINE/foo/is;
Le résultat peut être utilisé comme motif dans une recherche de correspondance :
$re = qr/$motif/;
$string =~ /foo${re}bar/;
# peut être interpolée dans d’autres motifs
$string =~ $re;
# ou utilisée seule
$string =~ /$re/;
# ou de cette manière
Puisque Perl peut compiler le motif lors de l’exécution de l’opérateur qr(), l’utilisation de qr() peut augmenter les performances
dans quelques situations, notamment si le résultat de qr() est utilisé seul :
sub match {
my $patterns = shift;
my @compiled = map qr/$_/i, @$patterns;
grep {
my $success = 0;
foreach my $pat @compiled {
$success = 1, last if /$pat/;
}
$success;
} @_;
}
La précompilation du motif en une représentation interne lors du qr() évite une recompilation à chaque fois qu’une recherche
/$pat/ est tentée. (Notez que Perl a de nombreuses autres optimisations internes mais aucune n’est déclenchée dans l’exemple
précédent si nous n’utilisons pas l’opérateur qr().)
Les options sont :
i
Motif indépendant de la casse (majuscules/minuscules).
m
Traitement de chaîne comme étant multi-lignes.
o
Compilation du motif uniquement la première fois.
s
Traitement de la chaîne comme étant une seule ligne.
x
Utilisation des expressions rationnelles étendues.
Voir le manuel perlre pour de plus amples informations sur la syntaxe correcte de CHAINE et pour une description détaillée
de la sémantique des expressions rationnelles.
qx/CHAINE/
‘CHAINE‘
Une chaîne qui est (éventuellement) interpolée puis exécutée comme une commande système par /bin/sh ou équivalent. Les
jokers, tubes (pipes) et redirections sont pris en compte. L’ensemble de la sortie standard de la commande est renvoyé ; la
sortie d’erreur n’est pas affectée. Dans un contexte scalaire, le résultat est retourné comme une seule chaîne (potentiellement
multi-lignes). Dans un contexte de liste, le résultat est une liste de lignes (selon la dé?nition des lignes donnée par $/ ou
$INPUT_RECORD_SEPARATOR).
Puisque les apostrophes inverses (backticks) n’affectent pas la sortie d’erreur, il vous faut utiliser la (les) syntaxe(s) de redi-
rection du shell (en supposant qu’elle(s) existe(nt)) a?n de capter les erreurs. Pour récupérer les sorties STDOUT et STDERR
d’une commande :
$output = ‘cmd 2>&1‘;
Pour récupérer STDOUT et faire disparaître STDERR :
$output = ‘cmd 2>/dev/null‘;
Pour récupérer STDERR et faire disparaître STDOUT (l’ordre est ici très important) :
$output = ‘cmd 2>&1 1>/dev/null‘;
Pour échanger STDOUT et STDERR a?n de récupérer STDERR tout en laissant STDOUT s’af?cher normalement :
$output = ‘cmd 3>&1 1>&2 2>&3 3>&-‘;
40

5.2. DESCRIPTION
perlop
Pour récupérer STDOUT et STDERR séparément, il est plus simple et sain de les rediriger séparément vers des ?chiers qui
seront lus lorsque l’exécution de la commande sera terminée :
system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr");
L’utilisation de l’apostrophe comme délimiteur protège la commande de l’interpolation normalement effectuée par Perl sur les
chaînes entre guillemets. La chaîne est passée tel quelle au shell :
$perl_info
= qx(ps $$);
# Le $$ de Perl
$shell_info = qx’ps $$’;
# Le $$ du nouveau shell
Remarquez que la manière dont la chaîne est évaluée est entièrement dépendante de l’interpréteur de commandes de votre
système. Sur la plupart des plates-formes, vous aurez à protéger les méta-caractères du shell si vous voulez qu’ils soient
traités littéralement. En pratique, c’est dif?cile à faire, surtout qu’il n’est pas toujours facile de savoir quels caractères doivent
être protégés. Voir le manuel perlsec pour un exemple propre et sûre d’utilisation manuelle de fork() et exec() pour émuler
proprement l’utilisation des backticks.
Sur certaines plates-formes (particulièrement celles style DOS) le shell peut ne pas être capable de gérer des commandes
multi-lignes. Dans ce cas, l’usage de passages à la ligne dans la chaîne de commande ne donne pas ce que vous voulez. Vous
pouvez évaluez plusieurs commandes sur une seule et même ligne et les séparant par le caractère de séparation de commandes
si votre shell le supporte (e.g. ; pour la plupart des shells Unix; & sur le cmd shell de Windows NT).
Depuis la version v5.6.0, Perl tente de vider les tampons de tous les ?chiers ouverts en écriture avant de lancer la commande
mais cela n’est pas supporté sur toutes les plates-formes (voir le manuel perlport). Pour être plus sûr, vous devriez posi-
tionné la variable $| ($AUTOFLUSH en anglais) ou appelé la méthode autoflush() des objets IO::Handle pour chacun des
descripteurs ouverts.
N’oubliez pas que certains shells ont quelques restrictions sur la longueur de la ligne de commande. Vous devez vous assurer
que votre chaîne n’excède pas cette limite même après interpolation. Voir les notes spéci?ques à votre plate-forme pour plus
de détails sur votre environnement particulier.
L’utilisation de cet opérateur peut aboutir à des programmes dif?ciles à porter puisque les commandes shells appelées varient
d’un système à l’autre et peuvent parfois ne pas exister du tout. À titre d’exemple, la commande type du shell POSIX est très
différente de la commande type sous DOS. Cela ne signi?e pas qu’il vous faut à tout prix éviter cet opérateur lorsque c’est le
bon moyen de faire ce que vous voulez. Perl a été conçu pour être un "glue language"  La seule chose qui compte c’est que
vous sachiez ce que vous faites.
Voir §5.2.29 pour des plus amples informations.
qw/CHAINE/
Retourne la liste des mots extraits de CHAINE en utilisant les espaces comme délimiteurs de mots. On peut le considérer
comme équivalent à :
split(’ ’, q/CHAINE/);
avec comme différence que la liste est générée lors de la compilation. Donc <l’expression :>
qw(foo bar baz)
est sémantiquement équivalente à la liste :
’foo’, ’bar’, ’baz’
Quelques exemples fréquemment rencontrés :
use POSIX qw( setlocale localeconv )
@EXPORT = qw( foo bar baz );
Une erreur assez commune consiste à séparer les mots par des virgules ou à mettre des commentaires dans une qw-chaîne
multi-lignes. C’est la raison pour laquelle use warnings ou l’option -w (c’est à dire la variable $ˆW) produit un message
d’avertissement lorsque CHAINE contient le caractère "," ou le caractère "#".
s/MOTIF/REMPLACEMENT/egimosx
Recherche le motif dans une chaîne puis, s’il est trouvé, le substitue par le texte de REMPLACEMENT et retourne ?nalement
le nombre de substitutions effectuées. Sinon, renvoie faux (en l’espèce, la chaîne vide).
Si aucune chaîne n’est spéci?ée via =˜ ou !˜, la recherche et la substitution s’appliquent à la variable $_. (La chaîne spéci?ée
par =˜ doit être une variable scalaire, un élément d’un tableau ou d’une table de hachage ou une affectation de l’un ou de
l’autre  en un mot, une lvalue.)
Si le délimiteur choisi est l’apostrophe, aucune interpolation n’est effectuée ni sur MOTIF ni sur REMPLACEMENT. Sinon,
si MOTIF contient un $ qui ressemble plus à une variable qu’à un test de ?n de chaîne, la variable sera interpolée dans le motif
41

5.2. DESCRIPTION
perlop
lors de l’exécution. Si vous voulez que le motif ne soit compilé qu’une seule fois la première fois que la variable est interpolée,
utilisez l’option /o. Si l’évaluation du motif est la chaîne nulle, la dernière expression rationnelle reconnue est utilisée à la
place. Voir le manuel perlre pour de plus amples informations à ce sujet. Voir le manuel perllocale pour des informations
supplémentaires qui s’appliquent lors de l’usage de use locale.
Les options sont :
e
Évaluez la partie droite comme une expression.
g
Substitution globale, i.e. toutes les occurrences.
i
Motif indépendant de la casse (majuscules/minuscules).
m
Traitement de chaîne comme étant multi-lignes.
o
Compilation du motif uniquement la première fois.
s
Traitement de la chaîne comme étant une seule ligne.
x
Utilisation des expressions rationnelles étendues.
N’importe quel délimiteur (ni blanc ni alphanumérique) peut remplacer les barres obliques (slash). Si l’apostrophe est utilisée,
aucune interpolation n’est effectuée sur la chaîne de remplacement (par contre, le modi?cateur /e passe outre). Au contraire
de Perl 4, Perl 5 considère l’accent grave (backtick) comme un délimiteur normal ; le texte de remplacement n’est pas évalué
comme une commande. Si le MOTIF est délimité par des caractères fonctionnant en paire (comme les parenthèses), le texte
de REMPLACEMENT a sa propre paire de délimiteurs qui peuvent être ou non des caractères fonctionnant par paire, e.g.
s(foo)(bar) ou s<foo>/bar/. L’option /e implique que la partie remplacement sera interprétée comme une expression
Perl à part entière et donc évaluée comme telle. Par contre, sa validité syntaxique est évaluée lors de la compilation. Un
seconde option e provoquera l’évaluation de la partie REMPLACEMENT avant son exécution en tant qu’expression Perl.
Exemples:
s/\bgreen\b/mauve/g;
# ne modifie pas wintergreen
$path =~ s|/usr/bin|/usr/local/bin|;
s/Login: $foo/Login: $bar/; # motif dynamique
($foo = $bar) =~ s/this/that/;
# recopie puis modification
$count = ($paragraph =~ s/Mister\b/Mr./g);
# calcul du nombre de substitution
$_ = ’abc123xyz’;
s/\d+/$&*2/e;
# produit ’abc246xyz’
s/\d+/sprintf("%5d",$&)/e;
# produit ’abc
246xyz’
s/\w/$& x 2/eg;
# produit ’aabbcc
224466xxyyzz’
s/%(.)/$percent{$1}/g;
# pas de /e
s/%(.)/$percent{$1} || $&/ge;
# une expression donc /e
s/^=(\w+)/&pod($1)/ge;
# appel de fonction
# expansion des variables dans $_, mais dynamique uniquement
# en utilisant le déréférencement symbolique
s/\$(\w+)/${$1}/g;
# Ajoute un à chaque nombre présent dans la chaîne
s/(\d+)/1 + $1/eg;
# Ceci développe toutes les variables scalaires incluses
# (même les lexicales) dans $_ : $1 est tout d’abord interpolé
# puis évalué
s/(\$\w+)/$1/eeg;
# Suppression des commentaires C (presque tous).
$program =~ s {
/\*
# Reconnais le début du commentaire
.*?
# Reconnais un minimum de caractères
\*/
# Reconnais la fin de commentaire
} []gsx;
s/^\s*(.*?)\s*$/$1/;
# suppression des espaces aux extrémités de $_ (couteux)
for ($variable) {
# suppression des espaces aux extrémités de $variable (efficace)
s/^\s+//;
s/\s+$//;
}
42

5.2. DESCRIPTION
perlop
s/([^ ]*) *([^ ]*)/$2 $1/;
# inverse les deux premiers champs
Remarquez l’usage de $ à la place de \ dans le dernier exemple. À l’inverse de sed, nous utilisons la forme \<digit> unique-
ment dans la partie gauche. Partout ailleurs, c’est $<digit>.
Dans certains cas, il ne suf?t pas de mettre /g pour modi?er toutes les occurrences. Voici quelques cas communs :
# placer des virgules correctement dans un entier
# (NdT: en français, on mettrait des espaces)
1 while s/(.*\d)(\d\d\d)/$1,$2/g;
# perl4
1 while s/(\d)(\d\d\d)(?!\d)/$1,$2/g;
# perl5
# remplacement des tabulations par 8 espaces
1 while s/\t+/’ ’ x (length($&)*8 - length($‘)%8)/e;
tr/LISTERECHERCHEE/LISTEREMPLACEMENT/cds
y/LISTERECHERCHEE/LISTEREMPLACEMENT/cds
Translittère chacune des occurrences des caractères de la liste recherchée par le caractère correspondant de la liste de rem-
placement. Cette opérateur retourne le nombre de caractères remplacés ou supprimés. Si aucune chaîne n’est spéci?é via =˜
ou !˜, la translittération s’applique à $_. (La chaîne spéci?ée par =˜ doit être une variable scalaire, un élément d’un tableau ou
d’un table de hachage ou une affectation de l’un ou de l’autre  en un mot, une lvalue.)
Un intervalle de caractères peut-être spéci?é grâce à un tiret. Donc tr/A-J/0-9/ effectue les mêmes translittérations que
tr/ACEGIBDFHJ/0246813579/. Pour les adeptes de sed, y est fourni comme un synonyme de tr. Si la liste recherchée est
délimitée par des caractères fonctionnant par paire (comme les parenthèses) alors la liste de remplacement a ses propres
délimiteurs, e.g. tr[A-Z][a-z] ou tr(+\-*/)/ABCD/.
Remarquez aussi que le concept d’intervalle de caractères n’est pas vraiment portable entre différents codages – et même dans
un même codage, cela peut produire un résultat que vous n’attendez pas. Un bon principe de base est de n’utiliser que des
intervalles qui commencent et se terminent dans le même alphabet ([a-e], [A-E]) ou dans les chiffres ([0-9]). Tout le reste n’est
pas sûr. Dans le doute, énumérez l’ensemble des caractères explicitement.
Les options (ou modi?cateurs) :
c
Complémente la SEARCHLIST.
d
Efface les caractères trouvés mais non remplacés.
s
Agrège les caractères de remplacement dupliqués.
U
Transcrit vers/depuis UTF-8
C
Transcrit vers/depuis des caractères 8-bit (octet).
Si le modi?cateur /c est utilisé, c’est le complément de la liste recherchée qui est utilisé. Si le modi?cateur /d est spéci?é,
tout caractère spéci?é dans LISTERECHERCHEE et sans équivalent dans LISTEREMPLACEMENT est effacé. (Ceci est tout
de même plus ?exible que le comportement de certains programme tr qui efface tout ce qui est dans LISTERECHERCHEE,
point!) Si le modi?cateur /s est spéci?é, les suites de caractères qui sont translittérés par le même caractère sont agrégées en
un seul caractère.
Si le modi?cateur /d est utilisé, LISTEREMPLACEMENT est toujours interprété exactement comme spéci?é. Sinon, si LIS-
TEREMPLACEMENT est plus court que LISTERECHERCHEE, le dernier caractère est répété autant de fois que nécessaire
pour obtenir la même longueur. Si LISTEREMPLACEMENT est vide, LISTERECHERCHEE est utilisé à la place. Ce dernier
point est très pratique pour comptabiliser les occurrences d’une classe de caractères ou pour agréger les suites de caractères
d’une classe.
Le premier modi?cateur /U ou /C s’applique à la partie gauche de la transcription. Le second s’applique à la parti droite.
Lorsqu’ils sont présents, ces modi?cateurs passent outre l’état utf8 courant.
Exemples :
$ARGV[1] =~ tr/A-Z/a-z/;
# tout en minuscule
$cnt = tr/*/*/;
# compte les étoiles dans $_
$cnt = $sky =~ tr/*/*/;
# compte les étoiles dans $sky
$cnt = tr/0-9//;
# compte les chiffres dans $_
tr/a-zA-Z//s;
# bookkeeper -> bokeper
($HOST = $host) =~ tr/a-z/A-Z/;
tr/a-zA-Z/ /cs;
# remplace tous les non alphanumériques
# par un seul espace
43

5.2. DESCRIPTION
perlop
tr [\200-\377]
[\000-\177];
# efface le 8ème bit.
tr/\0-\xFF//CU;
# change Latin-1 to Unicode
tr/\0-\x{FF}//UC;
# change Unicode to Latin-1
Si plusieurs caractères de translittération sont donnés pour un caractère, seul le premier est utilisé :
tr/AAA/XYZ/
translittérera tous les A en X.
Remarquez que puisque la table de translittération est construite lors de la compilation, ni LISTERECHERCHEE ni LISTE-
REMPLACEMENT ne sont sujettes à l’interpolation de chaîne entre guillemets. Cela signi?e que si vous voulez utiliser des
variables, vous devez utiliser eval() :
eval "tr/$oldlist/$newlist/";
die $@ if $@;
eval "tr/$oldlist/$newlist/, 1" or die $@;
5.2.28
Les détails sordides de l’interprétation des chaînes
Face à quelque chose qui pourrait avoir différentes interprétations, Perl utilise le principe du FCQJP (qui signi?e Fait Ce Que Je
Pense) pour choisir l’interprétation la plus probable. Cette stratégie fonctionne tellement bien que les utilisateurs de Perl soupçonnent
rarement l’ambiguïté de ce qu’ils écrivent. Par contre, de temps à autre, l’idée que se fait Perl diffère de ce que l’auteur du programme
pensait.
L’objet de cette partie est de clari?er la manière dont Perl interprète les chaînes. La raison la plus fréquente pour laquelle quel-
qu’un a besoin de connaître tous ces détails est l’utilisation d’une expression rationnelle "velue". Par contre, les premiers pas de
l’interprétation d’une chaîne sont les mêmes pour toutes les constructions de chaînes. Ils sont donc expliqués ensemble.
L’étape la plus importante de l’interprétation des chaînes dans Perl est la première exposée ci-dessous : lors d’une interprétation de
chaînes, Perl cherche d’abord la ?n de la construction puis il interprète le contenu de cette construction. Si vous comprenez cette
règle, vous pouvez sauter les autres étapes en première lecture. Contrairement à cette première étape, les autres étapes contredisent
beaucoup moins souvent les attentes de l’utilisateur.
Quelques-unes des passes exposées plus loin sont effectuées simultanément. Mais comme le résultat est le même, nous les consi-
dérerons successivement une par une. Selon la construction, Perl effectue ou non certaines passes (de une à cinq) mais elles sont
toujours appliquées dans le même ordre.
Trouver la ?n
La première passe consiste à trouver la ?n de la construction qui peut être la suite de caractères "\nEOF\n" d’une construction
<<EOF, le / qui termine une construction qq/, le ] qui termine une construction qq[ ou le > qui termine un ?leglob commencé
par <.
Lors de la recherche d’un caractère délimiteur non appairé comme /, les combinaisons comme \\ et \/ sont sautées. Lors de la
recherche d’un délimiteur appairé comme ], les combinaisons \\, \] et \[ sont sautées ainsi que les constructions imbriquées
[ ]. Lors de la recherche d’une suite de caractères, rien n’est omis.
Pour les constructions en trois parties (s///, y/// et tr///), la recherche est répétée une fois supplémentaire.
Lors de cette recherche, aucune attention n’est accordée à la sémantique de la construction, donc :
"$hash{"$foo/$bar"}"
ou :
m/
bar
#
Ce n’est PAS un commentaire, ce slash / termine m// !
/x
ne constituent donc pas des constructions légales. L’expression se termine au premier " ou / et le reste apparaît comme une
erreur de syntaxe. Remarquez que puisque le slash qui termine m// est suivi pas un ESPACE, ce n’est pas une constructions
m//x et donc # est interprété comme un # littéral.
Suppression des barres obliques inverses (backslash) précédents les délimiteurs
Lors de la seconde passe, le texte entre le délimiteur de départ et le délimiteur de ?n est recopié à un endroit sûr et le \
des combinaisons constituées par un \ suivi du délimiteur (ou des délimiteurs si celui de départ diffère de celui de ?n) est
supprimé. Cette suppression n’a pas lieu pour des délimiteurs multi-caractères.
Remarquez que la combinaison \\ est laissée telle quelle.
À partir de ce moment plus aucune information concernant le(s) délimiteur(s) n’est utilisée.
44

5.2. DESCRIPTION
perlop
Interpolation
L’étape suivante est l’interpolation appliquée au texte isolé de ses délimiteurs. Il y a quatre cas différents.
<<’EOF’, m”, s”’, tr///, y///
Aucune interpolation n’est appliquée.
”, q//
La seule interpolation est la suppression du \ des paires \\.
"", “, qq//, qx//, <file*glob>
Les \Q, \U, \u, \L, \l (éventuellement associé avec \E) sont transformés en leur construction Perl correspondante et
donc "$foo\Qbaz$bar" est transformé en $foo . (quotemeta("baz" . $bar)) en interne. Les autres combinaisons
constituées d’un \ suivi d’un ou plusieurs caractères sont remplacées par le ou les caractères appropriés.
Soyez conscient que tout ce qui est entre \Q et \est interpolé de manière classique. Donc "\Q\\E" ne contient pas de
\E : il contient \Q, \\ et E donc le résultat est le même que "\\\\E". Plus généralement, la présence de backslash entre
\Q et \E aboutit à des résultats contre-intuitifs. Donc "\Q\t\E" est converti en quotemeta("\t") qui est la même chose
que "\\\t" (puisque TAB n’est pas alphanumérique). Remarquez aussi que :
$str = ’\t’;
return "\Q$str";
est peut-être plus proche de l’intention de celui qui écrit "\Q\t\E".
Les scalaires et tableaux interpolés sont convertis en une série d’opérations de concaténation join et .. Donc "$foo XXX
’@arr’" devient :
$foo . " XXX ’" . (join $", @arr) . "’";
Toutes les étapes précédentes sont effectuées simultanément de la gauche vers la droite.
Puisque le résultat de "\Q STRING \E" a tous ses méta-caractères quotés, il n’y aucun moyen d’insérer littéralement un
$ ou un @ dans une paire \Q\E : si il est protégé par \, un $ deviendra "\\\$" et sinon il sera interprété comme le début
d’un scalaire a interpolé.
Remarquez aussi que l’interpolation de code doit décider où se termine un scalaire interpolé. Par exemple "a $b ->
{c}" peut signi?er :
"a " . $b . " -> {c}";
ou :
"a " . $b -> {c};
Dans la plupart des cas, le choix est de considérer le texte le plus long possible n’incluant pas d’espaces entre ses
composants et contenant des crochets ou accolades bien équilibrés. Puisque le résultat peut-être celui d’un vote entre
plusieurs estimateurs heuristiques, le résultat n’est pas strictement prévisible. Heureusement, il est habituellement correct
pour les cas ambigus.
?RE?, /RE/, m/RE/, s/RE/foo/,
Le traitement des \Q, \U, \u, \L, \l et des interpolations est effectué quasiment de la même manière qu’avec les construc-
tions qq// sauf que la substitution d’un \ suivi d’un ou plusieurs caractères spéciaux pour les expressions rationnelles
(incluant \) n’a pas lieu. En outre, dans les constructions (?{BLOC}), (?# comment ), et #-comment présentes dans
les expressions rationnelles //x, aucun traitement n’est effectué. C’est le premier cas ou la présence de l’option //x est
signi?cative.
L’interpolation a quelques bizarreries : $|, $( et $) ne sont pas interpolés et les constructions comme $var[QQCH]
peuvent être vues (selon le vote de plusieurs estimateurs différents) soit comme un élément d’un tableau soit comme
$var suivi par une alternative RE. C’est là où la notation ${arr[$bar]} prend tout sons intérêt : /${arr[0-9]}/ est
interprété comme l’élément -9 du tableau et pas comme l’expression rationnelle contenu dans $arr suivie d’un chiffre
(qui est l’interprétation de /$arr[0-9]/). Puisqu’un vote entre différents estimateurs peut avoir lieu, le résultat n’est pas
prévisible.
C’est à ce moment que la construction \1 est convertie en $1 dans le texte de remplacement de s/// pour corriger
les incorrigibles adeptes de sed qui n’ont pas encore compris l’idiome. Un avertissement est émis si le pragma use
warnings ou l’option -w (c’est à dire la variable $ˆW) est actif.
Remarquez que l’absence de traitement de \\ crée des restrictions spéci?ques sur le texte après traitement: si le délimiteur
est /, on ne peut pas obtenir \/ comme résultat de cette étape (/ ?nirait l’expression rationnelle, \/ serait transformé
en / par l’étape précédente et \\/ serait laissé tel quel). Puisque / est équivalent à \/ dans une expression rationnelle,
ceci ne pose problème que lorsque le délimiteur est un caractère spécial pour le moteur RE comme dans s*foo*bar*,
m[foo], ou ?foo? ou si le délimiteur est un caractère alphanumérique comme dans :
45

5.2. DESCRIPTION
perlop
m m ^ a \s* b mmx;
Dans l’expression rationnelle ci-dessus qui est volontairement obscure pour l’exemple, le délimiteur est m, le modi?cateur
est mx et après la suppression des backslash, l’expression est la même que m/ ˆ a s* b /mx. Il y a de nombreuses
raisons de vous encourager à ne choisir que des caractères non alphanumériques et non blancs comme séparateur.
Cette étape est la dernière pour toutes les constructions sauf pour les expressions rationnelles qui sont traitées comme décrit
ci-après.
Interpolation des expressions rationnelles
Toutes les étapes précédentes sont effectuées lors de la compilation du code Perl alors que celle que nous décrivons ici l’est a
priori lors de l’exécution (bien qu’elle soit parfois effectuée lors de la compilation pour des raisons d’optimisation). Après tous
les pré-traitements précédents (et évaluation des éventuels concaténations, jointures, changements de casse et applications de
quotemeta() déduits), la chaîne résultante est transmise au moteur RE pour compilation.
Ce qui se passe à l’intérieur du moteur RE est bien mieux expliqué dans le manuel perlre mais dans un souci de continuité,
nous l’exposons un peu ici.
Voici donc une autre étape où la présence du modi?cateur //x est prise en compte. Le moteur RE explore la chaîne de gauche
à droite et la convertit en un automate à états ?nis.
Les caractères "backslashés" sont alors remplacés par la chaîne correspondante (comme pour \{) ou génèrent des noeuds
spéciaux dans l’automate à états ?nis (comme pour \b). Les caractères ayant un sens spécial pour le moteur RE (comme
|) génèrent les noeuds ou les groupes de noeuds correspondants. Les commentaires (?# ) sont ignorés. Tout le reste est
converti en chaîne littérale à reconnaître ou est ignoré (par exemple les espaces et les commentaires # si le modi?cateur //x
est présent).
Remarquez que le traitement de la construction [ ] est effectué en utilisant des règles complètement différentes du reste de
l’expression rationnelle. Le terminateur de cette construction est trouvé en utilisant les mêmes règles que celles utilisées pour
trouver le terminateur d’une construction délimitée (comme {}). La seule exception est le ] qui suit immédiatement le [ et qui
est considéré comme précédé d’un backslash. De manière similaire, la construction (?{ }) n’est explorée que pour véri?er
que les parenthèses, crochets et autres accolades sont bien équilibrés.
Il est possible d’inspecter la chaîne envoyée au moteur RE ainsi que l’automate à états ?nis résultant. Voir les arguments
debug/debugcolor de la directive use le manuel re et/ou l’option Perl -Dr dans le titre Options de Ligne de Commande
dans le manuel perlrun.
Optimisation des expressions rationnelles
Cette étape n’est citée que dans un souci de complétude. Puisque elle ne change en rien la sémantique, les détails de cette
étape ne sont pas documentés et sont susceptibles d’évoluer. Cette étape est appliquée à l’automate à états ?nis généré lors des
étapes précédentes.
C’est lors de cette étape que split() optimise silencieusement /ˆ/ en /ˆ/m.
5.2.29
Les opérateurs d’E/S
Il y a plusieurs opérateurs d’E/S (Entrée/Sortie) que vous devez connaître.
Une chaîne entourée d’apostrophes inversées (accents graves) subit tout d’abord une substitution des variables exactement comme
une chaîne entre guillemets. Elle est ensuite interprétée comme une commande et la sortie de cette commande est la valeur du pseudo-
littéral comme avec un shell. Dans un contexte scalaire, la valeur retournée est une seule chaîne constituée de toutes les lignes de la
sortie. Dans un contexte de liste, une liste de valeurs est retournée, chacune des ces valeurs contenant une ligne de la sortie. (Vous
pouvez utilisez $/ pour utiliser un terminateur de ligne différent.) La commande est exécutée à chaque fois que le pseudo-littéral est
évalué. La valeur du statut de la commande est retournée dans $? (voir le manuel perlvar pour l’interprétation de $?). À l’inverse de
csh, aucun traitement n’est appliqué aux valeurs retournées – les passages à la ligne restent des passages à la ligne. A l’inverse de la
plupart des shells, les apostrophes inversées n’empêchent pas l’interprétation des noms de variables dans la commande. Pour passer
littéralement un $ au shell, vous devez le protéger en le pré?xant par un backslash (barre oblique inversée). La forme générale des
apostrophes inversées est qx//. (Puisque les apostrophes inversées impliquent toujours un passage par l’interprétation du shell, voir
le manuel perlsec pour tout ce qui concerne la sécurité.)
Dans un contexte scalaire, évaluer un ?lehandle entre supérieur/inférieur produit le ligne suivante de ce ?chier (saut à la ligne inclus
si il y a lieu) ou undef à la ?n du ?chier. Lorsque $/ a pour valeur undef (i.e. le mode ?le slurp) et que le ?chier est vide, ” est
retourné lors de la première lecture puis ensuite undef.
Normalement vous devez affecter cette valeur à une variable mais il y a un cas où une affectation automagique a lieu. Si et seulement
si cette opérateur d’entrée est la seule chose présente dans la condition d’une boucle while ou for(;;) alors la valeur est automa-
giquement affectée à la variable $_. (Cela peut vous sembler bizarre, mais vous utiliserez de telles constructions dans la plupart des
scripts Perl que vous écrirez.) La variable $_ n’est pas implicitement local-isée. Vous devrez donc le faire explicitement en mettant
local $_;.
Les lignes suivantes sont toutes équivalentes :
46

5.2. DESCRIPTION
perlop
while (defined($_ = <STDIN>)) { print; }
while ($_ = <STDIN>) { print; }
while (<STDIN>) { print; }
for (;<STDIN>;) { print; }
print while defined($_ = <STDIN>);
print while ($_ = <STDIN>);
print while <STDIN>;
et celle-ci a un comportement similaire mais sans utiliser $_ :
while (my $line = <STDIN>) { print $line }
Dans ces constructions, la valeur affectée (que ce soit automagiquement ou explicitement) est ensuite testée pour savoir si elle est
dé?nie. Ce test de dé?nition évite les problèmes avec des lignes qui ont une valeur qui pourrait être interprétée comme fausse par
perl comme par exemple "" ou "0" sans passage à la ligne derrière. Si vous voulez réellement tester la valeur de la ligne pour terminer
votre boucle, vous devrez la tester explicitement :
while (($_ = <STDIN>) ne ’0’) {   }
while (<STDIN>) { last unless $_;   }
Dans tous les autres contextes booléens, <filehandle> sans un test explicite de dé?nition (par defined) déclenchera un message
d’avertissement si le pragma use warnings ou l’option -w (c’est à dire la variable $ˆW) est actif.
Les ?lehandles STDIN, STDOUT, et STDERR sont prédé?nis. (Les ?lehandles stdin, stdout, et stderr fonctionnent aussi ex-
ceptés dans les packages où ils sont interprétés comme des identi?ants locaux.) Des ?lehandles supplémentaires peuvent être créés
par la fonction open(). Voir le manuel perlopentut et le titre open dans le manuel perlfunc pour plus de détails.
Si <FILEHANDLE> est utilisé dans un contexte de liste, une liste constituée de toutes les lignes est retournée avec une ligne par
élément de la liste. Il est facile d’utiliser de grande quantité de mémoire par ce moyen. Donc, à utiliser avec précaution.
<FILEHANDLE> peut aussi être écrit readline(*FILEHANDLE). Voir le titre readline dans le manuel perlfunc.
Le ?lehandle vide <> est spécial et peut être utiliser pour émuler le comportement de sed et de awk. L’entrée de <> provient soit
de l’entrée standard soit de tous les ?chiers listés sur la ligne de commande. Voici comment ça marche : la première fois que <> est
évalué, on teste le tableau @ARGV et s’il est vide alors $ARGV[0] est positionné à "-" qui lorsqu’il sera ouvert lira l’entrée standard.
Puis le tableau @ARGV est traité comme une liste de nom de ?chiers. La boucle :
while (<>) {

# code pour chaque ligne
}
est équivalent au pseudo-code Perl suivant :
unshift(@ARGV, ’-’) unless @ARGV;
while ($ARGV = shift) {
open(ARGV, $ARGV);
while (<ARGV>) {

# code pour chaque ligne
}
}
sauf qu’il est moins volumineux et qu’il marche réellement. Il décale vraiment le tableau @ARGV et stocke le nom du ?chier
courant dans la variable $ARGV. Il utilise aussi en interne le ?lehandle ARGV – <> est simplement un synonyme de <ARGV> qui
est magique. (Le pseudo-code précédent ne fonctionne pas car il tient pas compte de l’aspect magique de <ARGV>.)
Vous pouvez modi?er @ARGV avant la premier <> tant que vous y laissez la liste des noms de ?chiers que vous voulez. Le numéro
de ligne ($.) augmente exactement comme si vous aviez un seul gros ?chier. Regardez l’exemple de eof pour savoir comment le
réinitialiser à chaque ?chier.
Si vous voulez affecter à @ARGV votre propre liste de ?chiers, procédez de la manière suivante. La ligne suivante positionne
@ARGV à tous les ?chiers de type texte si aucun @ARGV n’est fourni :
@ARGV = grep { -f && -T } glob(’*’) unless @ARGV;
Vous pouvez même les positionner avec des commandes pipe (tube). Par exemple, la ligne suivante applique automatiquement gzip
aux arguments compressés :
47

5.2. DESCRIPTION
perlop
@ARGV = map { /\.(gz|Z)$/ ? "gzip -dc < $_ |" : $_ } @ARGV;
Si vous voulez passer des options à votre script, vous pouvez utiliser l’un des modules Getopts ou placer au début de votre script une
boucle du type :
while ($_ = $ARGV[0], /^-/) {
shift;
last if /^--$/;
if (/^-D(.*)/) { $debug = $1 }
if (/^-v/)
{ $verbose++
}

# autres options
}
while (<>) {

# code pour chaque ligne
}
Le symbole <> retournera undef à la ?n des ?chiers une seule fois. Si vous l’appelez encore une fois après, il supposera que vous
voulez traiter une nouvelle liste @ARGV et, si vous n’avez pas rempli @ARGV, il traitera l’entrée STDIN.
Si la chaîne entre supérieur/inférieur est une référence à une variable scalaire (e.g. <$foo>) alors cette variable doit contenir le nom
du ?lehandle à utiliser comme entrée ou son typeglob ou une référence vers un typeglob. Par exemple :
$fh = \*STDIN;
$line = <$fh>;
Si ce qui est entre supérieur/inférieur n’est ni un ?lehandle, ni une simple variable scalaire contenant un nom de ?lehandle, un
typeglob ou une référence à un typeglob, il est alors interprété comme un motif de nom de ?chier à appliquer et ce qui est retourné
est soit la liste de tous les noms de ?chiers ou juste le nom suivant dans la liste selon le contexte. La distinction n’est faite que par la
syntaxe. Cela signi?e que <$x> est toujours la lecture d’une ligne à partir d’un handle indirect mais que <$hash{key}> est toujours
un motif de nom de ?chiers. Tout cela parce que $x est une simple variable scalaire alors que $hash{key} ne l’est pas – c’est un
élément d’une table de hachage.
Comme pour les chaînes entre guillemets, un niveau d’interprétation est appliqué au préalable mais vous ne pouvez pas dire <$foo>
parce que c’est toujours interprété comme un ?lehandle indirect (explications du paragraphe précédent). (Dans des versions anté-
rieures de Perl, les programmeurs inséraient des accolades pour forcer l’interprétation comme un motif de nom de ?chier: <${foo}>.
De nos jours, il est considéré plus propre d’appeler la fonction interne explicitement par glob($foo) qui est probablement la
meilleure façon de faire dans le premier cas.) Exemple :
while (<*.c>) {
chmod 0644, $_;
}
est équivalent à :
open(FOO, "echo *.c | tr -s ’ \t\r\f’ ’\\012\\012\\012\\012’|");
while (<FOO>) {
chop;
chmod 0644, $_;
}
sauf que la recherche des ?chiers est faite en interne par l’extension standard File::Glob. Bien sûr, le moyen le plus court d’obtenir
le résultat précédent est :
chmod 0644, <*.c>;
Un motif de noms de ?chier évalue ses arguments uniquement lorsqu’il débute une nouvelle liste. Toutes les valeurs doivent être lues
avant de recommencer. Dans un contexte de liste, cela n’a aucune importance puisque vous récupérez toutes les valeurs quoi qu’il
arrive. Dans un contexte scalaire, par contre, l’opérateur retourne la valeur suivante à chaque fois qu’il est appelé ou la valeur undef
à la ?n. Comme pour les ?lehandles un defined automatique est généré lorsque l’opérateur est utilisé comme test d’un while ou
d’un for - car sinon certains noms de ?chier légaux (e.g. un ?chier nommé 0) risquent de terminer la boucle. Encore une fois, undef
n’est retourné qu’une seule fois. Donc si vous n’attendez qu’une seule valeur, il vaut mieux écrire :
($file) = <blurch*>;
48

5.2. DESCRIPTION
perlop
que :
$file = <blurch*>;
car dans le dernier cas vous aurez soit un nom de ?chier soit faux.
Si vous avez besoin de l’interpolation de variables, il est dé?nitivement meilleur d’utiliser la fonction glob() parce que l’ancienne
notation peut être confondu avec la notation des ?lehandles indirects.
@files = glob("$dir/*.[ch]");
@files = glob($files[$i]);
5.2.30
Traitement des constantes
Comme en C, Perl évalue un certain nombre d’expressions lors de la compilation lorsqu’il peut déterminer que tous les arguments
d’un opérateur sont statiques et n’ont aucun effet de bord. En particulier, la concaténation de chaînes a lieu lors de la compilation
entre deux littéraux qui ne sont pas soumis à l’interpolation de variables. L’interprétation du backslash (barre oblique inversée) a lieu
elle aussi lors de la compilation. Vous pouvez dire :
’Now is the time for all’ . "\n" .
’good men to come to.’
qui sera réduit à une seule chaîne de manière interne. Vous pouvez aussi dire :
foreach $file (@filenames) {
if (-s $file > 5 + 100 * 2**16) {
}
}
le compilateur pré-calculera la valeur représentée par l’expression et l’interpréteur n’aura plus à le faire.
5.2.31
Opérateurs bit à bit sur les chaînes
Les chaînes de bits de longueur arbitraire peuvent être manipulées par les opérateurs bit à bit (˜ | & ˆ).
Si les opérandes d’un opérateur bit à bit sont des chaînes de longueurs différentes, les opérateurs | et ˆ agiront comme si l’opérande
le plus court était complété par des bits à zéro à droite alors que l’opérateur agira comme si l’opérande le plus long était tronqué
à la longueur du plus court. Notez que la granularité pour de telles extensions ou troncations est d’un ou plusieurs octets.
# Exemples ASCII
print "j p \n" ^ " a h";
# affiche "JAPH\n"
print "JA" | "
ph\n";
# affiche "japh\n"
print "japh\nJunk" & ’_____’;
# affiche "JAPH\n";
print ’p N$’ ^ " E<H\n";
# affiche "Perl\n";
Si vous avez l’intention de manipuler des chaînes de bits, vous devez être certain de fournir des chaînes de bits : si un opérande est un
nombre cela implique une opération bit à bit numérique. Vous pouvez explicitement préciser le type d’opération que vous attendez
en utilisant "" ou 0+ comme dans les exemples ci-dessous :
$foo =
150
|
105 ;
# produit 255
(0x96 | 0x69 vaut 0xFF)
$foo = ’150’ |
105 ;
# produit 255
$foo =
150
| ’105’;
# produit 255
$foo = ’150’ | ’105’;
# produit la chaîne ’155’ (si en ASCII)
$baz = 0+$foo & 0+$bar;
# les deux opérandes explicitement numériques
$biz = "$foo" ^ "$bar";
# les deux opérandes explicitement chaînes
Voir le titre vec dans le manuel perlfunc pour savoir comment manipuler des bits individuellement dans un vecteur de bits.
49

5.2. DESCRIPTION
perlop
5.2.32
Arithmétique entière
Par défaut Perl suppose qu’il doit effectuer la plupart des calculs arithmétiques en virgule ?ottante. Mais en disant :
use integer;
vous dites au compilateur qu’il peut utiliser des opérations entières (si il le veut) à partir de ce point et jusqu’à la ?n du bloc englobant.
Un BLOC interne peut contredire cette commande en disant :
no integer;
qui durera jusqu’à la ?n de ce BLOC. Notez que cela ne signi?e pas que tout et n’importe quoi devient entier mais seulement que
Perl peut utiliser des opérations entières si il le veut. Par exemple, même avec use integer. sqrt(2) donnera toujours quelque
chose comme 1.4142135623731.
Utilisés sur des nombres, les opérations bit à bit ("&", "|", "ˆ", "˜", "«", et "»") produisent toujours des résultats entiers. (Mais
voir aussi le titre Opérateurs bit à bit sur les chaînes dans ce document.) Par contre, use integer a encore une in?uence sur eux.
Par défaut, leurs résultats sont interprétés comme des entiers non-signés. Par contre, si use integer est actif, leurs résultats sont
interprétés comme des entiers signés. Par exemple, ˜0 est habituellement évalué comme un grande valeur entière. Par contre, use
integer; ˜0 donne -1 sur des machines à complément à deux.
5.2.33
Arithmétique en virgule ?ottante
Bien que use integer propose une arithmétique uniquement entière, il n’y a aucun moyen similaire d’imposer des arrondis ou des
troncations à un certain nombre de décimales. Pour arrondir à un nombre de décimales précis, la méthode la plus simple est d’utiliser
sprintf() ou printf().
Les nombres en virgule ?ottante ne sont qu’une approximation de ce que les mathématiciens appellent les nombres réels. Il y a
in?niment plus de réels que de ?ottants donc il faut arrondir quelques angles. Par exemple :
printf "%.20g\n", 123456789123456789;
#
produit 123456789123456784
Tester l’égalité ou l’inégalité exacte de nombres ?ottants n’est pas une bonne idée. Voici un moyen (relativement coûteux) pour
tester l’égalité de deux nombres ?ottants sur un nombre particulier de décimales. Voir le volume II de Knuth pour un traitement plus
robuste de ce sujet.
sub fp_equal {
my ($X, $Y, $POINTS) = @_;
my ($tX, $tY);
$tX = sprintf("%.${POINTS}g", $X);
$tY = sprintf("%.${POINTS}g", $Y);
return $tX eq $tY;
}
Le module POSIX (qui fait partie de la distribution standard de perl) implémente ceil(), ?oor() et un certain nombre d’autres fonctions
mathématiques et trigonométriques. Le module Math::Complex (qui fait partie de la distribution standard de perl) dé?nit de nom-
breuses fonctions mathématiques qui fonctionnent aussi bien sur des nombres réels que sur des nombres complexes. Math::Complex
n’est pas aussi performant que POSIX mais POSIX ne peut pas travailler avec des nombres complexes.
Arrondir dans une application ?nancière peut avoir de sérieuses implications et la méthode d’arrondi utilisée doit être spéci?ée
précisément. Dans ce cas, il peut être plus sûr de ne pas faire con?ance aux différents systèmes d’arrondi proposés par Perl mais
plutôt d’implémenter vous-mêmes la fonction d’arrondi dont vous avez besoin.
5.2.34
Les grands nombres
Les modules standard Math::BigInt et Math::BigFloat fournissent des variables arithmétiques en précision in?nie et redé?nissent
les opérateurs correspondants. Au prix d’un peu d’espace et de beaucoup de temps, ils permettent d’éviter les embûches classiques
associées aux représentations en précision limitée.
use Math::BigInt;
$x = Math::BigInt->new(’123456789123456789’);
print $x * $x;
# affiche +15241578780673678515622620750190521
Les modules non standard SSLeay::BN et Math::Pari founissent des fonctionnalités équivalentes (et même supérieures) avec de
meilleures performances.
50

5.3. VERSION FRANÇAISE
perlop
5.3
VERSION FRANÇAISE
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.0. Pour en savoir plus concernant ces traductions,
consultez ;.
5.4
TRADUCTION
Traduction initiale et mise à jour <v5.6.0 :> Paul Gaborit <>.
5.5
RELECTURE
Personne pour l’instant.
51

Chapitre 6
perlsub – Les sous-programmes de Perl
Les sous-programmes de Perl
6.1
SYNOPSIS
Pour déclarer des sous-programmes :
sub NAME;
# Une déclaration "en avant".
sub NAME(PROTO);
# idem, mais avec des prototypes
sub NAME : ATTRS;
# avec attributs
sub NAME(PROTO) : ATTRS;
# avec attributs et prototypes
sub NAME BLOCK
# Une déclaration et une définition.
sub NAME(PROTO) BLOCK
# idem, mais avec des prototypes
sub NAME : ATTRS BLOCK
# avec attributs
sub NAME(PROTO) : ATTRS BLOCK # avec attributs et prototypes
Pour dé?nir un sous-programme anonyme lors de l’exécution :
$subref = sub BLOCK;
# pas de prototype
$subref = sub (PROTO) BLOCK;
# avec prototype
$subref = sub : ATTRS BLOCK;
# avec attributs
$subref = sub (PROTO) : ATTRS BLOCK; # avec proto et attributs
Pour importer des sous-programmes :
use MODULE qw(NAME1 NAME2 NAME3);
Pour appeler des sous-programmes :
NAME(LIST);
# & est optionnel avec les parenthèses.
NAME LIST;
# Les parenthèses sont optionnelles si le
# sous-programme est prédéclaré ou importé.
&NAME(LIST);
# Court-circuite les prototypes.
&NAME;
# Rend la @_ courante visible par le
# sous-programme appelé.
6.2
DESCRIPTION
Comme beaucoup de langages, Perl fournit des sous-programmes dé?nis par l’utilisateur. Ils peuvent se trouver n’importe où dans
le programme principal, ils peuvent être chargés depuis d’autres ?chiers via les mots-clés do, require, ou use, ou être générés à la
volée en utilisant eval ou des sous-programmes anonymes (fermetures). Vous pouvez même appeler une fonction indirectement en
utilisant une variable contenant son nom ou une référence de CODE pointant sur lui.
Le modèle de Perl pour l’appel de fonction et le renvoi de valeurs est simple : tous les paramètres sont passés aux fonctions comme
une seule simple liste de scalaires, et toutes les fonctions renvoient de la même manière à leur appelant une seule simple liste
52

6.2. DESCRIPTION
perlsub
de scalaires. Tout tableau ou hachage dans ces listes d’appel et de retour s’effondreront, perdant leur identité – mais vous pouvez
toujours utiliser le passage par référence à la place pour éviter cela. Les listes d’appel ou de retour peuvent contenir autant d’éléments
scalaires que vous le désirez (une fonction sans instruction de retour explicite est souvent appelée un sous-programme, mais il n’y a
vraiment pas de différence dans la perspective de Perl).
Tous les arguments passés à la routine se retrouvent dans le tableau @_. Ainsi, si vous appelez une fonction avec deux arguments,
ceux-ci seront stockés dans $_[0] et $_[1]. Le tableau @_ est un tableau local, mais ses éléments sont des alias pour les véritables
paramètres scalaires. En particulier, si un élément $_[0] est mis à jour, l’argument correspondant est mis à jour (ou bien une erreur
se produit s’il n’est pas modi?able). Si un argument est un élément de tableau ou de hachage qui n’existait pas lors de l’appel de la
fonction, cet élément est créé seulement lorsque (et si) il est modi?é ou si on y fait référence (certaines versions précédentes de Perl
créaient l’élément qu’il soit ou non affecté). L’affectation à la totalité du tableau @_ retire les alias, et ne met à jour aucun argument.
La valeur de retour d’un sous-programme est la valeur de la dernière expression évaluée. De façon plus explicite, une instruction
return peut être utilisée pour sortir du sous-programme, en spéci?ant de façon optionnelle la valeur de retour, qui sera évaluée
dans le contexte approprié (liste, scalaire, ou vide) selon le contexte de l’appel du sous-programme. Si vous ne spéci?ez pas de
valeur de retour, le sous-programme renvoit une liste vide dans un contexte de liste, la valeur indé?nie dans un contexte scalaire,
ou rien dans un contexte vide. Si vous renvoyez un ou plusieurs aggrégats (tableau(x) et/ou hachage(s)), ils seront aplatis ensemble
indistinctement en une seule grosse liste.
Perl n’a pas de paramètres formels nommés. En pratique tout ce que vous avez à faire est d’affecter à une liste my() les contenant.
Les variables que vous utilisez dans la fonction et qui ne sont pas déclarées comme privées sont des variables globales. Pour des
détails sanglants sur la création de variables privées, voir §6.2.1 et §6.2.3. Pour créer des environnement protégés pour un ensemble
de fonctions dans un paquetage séparé (et probablement un ?chier séparé), voir le titre Paquetages dans le manuel perlmod.
Exemple :
sub max {
my $max = shift(@_);
foreach $foo (@_) {
$max = $foo if $max < $foo;
}
return $max;
}
$bestday = max($mon,$tue,$wed,$thu,$fri);
Exemple :
# obtient une ligne, en y combinant les lignes la continuant qui
# débutent par un blanc
sub get_line {
$thisline = $lookahead;
# Variables globales !!
LINE: while (defined($lookahead = <STDIN>)) {
if ($lookahead =~ /^[ \t]/) {
$thisline .= $lookahead;
}
else {
last LINE;
}
}
return $thisline;
}
$lookahead = <STDIN>;
# obtient la première ligne
while (defined($line = get_line()) {

}
Affectez à une liste de variables privées pour nommer vos arguments :
sub maybeset {
my($key, $value) = @_;
$Foo{$key} = $value unless $Foo{$key};
}
53

6.2. DESCRIPTION
perlsub
Puisque l’affectation copie les valeurs, ceci a aussi pour effet de transformer l’appel par référence en appel par valeur. Autrement,
une fonction est libre de faire des modi?cations de @_ sur place et de changer les valeurs de son appelant.
upcase_in($v1, $v2);
# ceci change $v1 et $v2
sub upcase_in {
for (@_) { tr/a-z/A-Z/ }
}
Vous n’avez pas le droit de modi?er les constantes de cette façon, bien sûr. Si un argument était en vérité un littéral et que vous
essayiez de le changer, vous lèveriez une exception (probablement fatale). Par exemple, ceci ne fonctionnera pas :
upcase_in("frederick");
Ce serait bien plus sûr si la fonction upcase_in() était écrite de façon à renvoyer une copie de ses paramètres au lieu de les changer
sur place :
($v3, $v4) = upcase($v1, $v2);
# cela ne change pas $v1 et $v2
sub upcase {
return unless defined wantarray;
# contexte vide, ne fait rien
my @parms = @_;
for (@parms) { tr/a-z/A-Z/ }
return wantarray ? @parms : $parms[0];
}
Notez comment cette fonction (non prototypée) ne se soucie pas qu’on lui ait passé de vrais scalaires ou des tableaux. Perl voit tous
les arguments comme une grosse et longue liste plate de paramètres dans @_. C’est un domaine dans lequel brille le style simple de
passage d’arguments de Perl. La fonction upcase() fonctionnerait parfaitement bien sans avoir à changer la dé?nition de upcase()
même si nous lui donnions des choses telles que ceci :
@newlist
= upcase(@list1, @list2);
@newlist
= upcase( split /:/, $var );
Ne vous laissez toutefois pas tenter de faire :
(@a, @b)
= upcase(@list1, @list2);
Tout comme la liste plate de paramètres entrante, la liste de retour est aussi aplatie. Donc tout ce que vous êtes parvenu à faire ici est
de tout stocker dans @a et de faire de @b une liste vide. Voir le titre Passage par Référence dans ce document pour des alternatives.
Un sous-programme peut être appelé en utilisant un pré?xe & explicite. Le & est optionnel en Perl moderne, tout comme le sont les
parenthèses si le sous-programme a été prédéclaré. Le & n’est pas optionnel lorsque l’on nomme juste le sous-programme, comme
lorsqu’il est utilisé en tant qu’argument de de?ned() ou de undef(). Il n’est pas non plus optionnel lorsque vous voulez faire un
appel indirect de sous-programme avec le nom d’un sous-programme ou une référence utilisant les constructions &$subref() ou
&{$subref}(), bien que la notation $subref->() résoud ce problème. Voir le manuel perlref pour plus de détails à ce sujet.
Les sous-programmes peuvent être appelés de façon récursive. Si un sous-programme est appelé en utilisant la forme &, la liste
d’arguments est optionnelle, et si elle est omise, aucun tableau @_ n’est mis en place pour le sous-programme : le tableau @_ au
moment de l’appel est visible à la place dans le sous-programme. C’est un mécanisme d’ef?cacité que les nouveaux utilisateurs
pourraient préférer éviter.
&foo(1,2,3);
# passe trois arguments
foo(1,2,3);
# idem
foo();
# passe une liste nulle
&foo();
# idem
&foo;
# foo() obtient les arguments courants, comme foo(@_) !!
foo;
# comme foo() SI le sous-programme foo est
# prédéclaré, sinon "foo"
Non seulement la forme & rend la liste d’arguments optionnelle, mais elle désactive aussi toute véri?cation de prototype sur les
arguments que vous fournissez. C’est en partie pour des raisons historiques, et en partie pour avoir une façon pratique de tricher si
vous savez ce que vous êtes en train de faire. Voir le manuel Prototypes ci-dessous.
Les fonctions dont les noms sont entièrement en majuscules sont réservées pour le noyau de Perl, tout comme les modules dont
les noms sont entièrement en minuscules. Une fonction entièrement en majuscules est une convention informelle signi?ant qu’elle
sera appelée indirectement par le système d’exécution lui-même, habituellement suite à un événement provoqué. Les fonctions qui
font des choses spéciales prédé?nies sont entre autres BEGIN, CHECK, INIT, END, AUTOLOAD, et DESTROY – plus toutes les fonctions
mentionnées dans le manuel perltie.
54

6.2. DESCRIPTION
perlsub
6.2.1
Variables Privées via my()
Synopsis:
my $foo;
# déclare $foo locale lexicalement
my (@wid, %get);
# déclare une liste de variables locale
my $foo = "flurp";
# déclare $foo lexical, et l’initialise
my @oof = @bar;
# déclare @oof lexical, et l’initialise
my $x : Foo = $y;
# similaire, avec application d’un attribut
L’opérateur my déclare que les variables listées doivent être con?nées lexicalement au bloc où elles se trouvent, dans la conditionnelle
(if/unless/elsif/else), la boucle (for/foreach/while/until/continue), le sous-programme, l’eval, ou le ?chier exécuté,
requis ou utilisé via do/require/use. Si plus d’une valeur est listée, la liste doit être placée entre parenthèses. Tous les éléments
listés doivent être des lvalues légales. Seuls les identi?ants alphanumériques peuvent avoir une portée lexicale – les identi?ants
magiques prédé?nis comme $/ doivent actuellement être à la place localisés par local.
Contrairement aux variables dynamiques créées par l’opérateur local, les variables lexicales déclarées par my sont totalement
cachées du monde extérieur, y compris de tout sous-programme appelé. Cela est vrai s’il s’agit du même sous-programme rappelé
depuis lui-même ou depuis un autre endroit – chaque appel obtient sa propre copie.
AVERTISSEMENT : l’usage de listes d’attributs sur les déclarations my est expérimental. On ne devrait pas faire con?ance à cette
caractéristique. Elle pourrait changer ou disparaître dans les prochaines versions de Perl. Voir le manuel attributes.
Ceci ne veut pas dire qu’une variable my() déclarée dans une portée lexicale englobante statiquement serait invisible. Seules les
portées dynamiques sont rétrécies. Par exemple, la fonction bumpx() ci-dessous a accès à la variable lexicale $x car le my et le sub
se sont produits dans la même portée, probablement la portée du ?chier.
my $x = 10;
sub bumpx { $x++ }
Un eval(), toutefois, peut voir les variables lexicales de la portée dans laquelle il est évalué, tant que les noms ne sont pas cachés
par des déclarations à l’intérieur de l’eval() lui-même. Voir le manuel perlref.
La liste de paramètres de my() peut être affectée si on le désire, ce qui vous permet d’initialiser vos variables (si aucune valeur
initiale n’est donnée à une variable particulière, celle-ci est créé avec la valeur indé?nie). Ceci est utilisé couramment pour nommer
les paramètres d’entrée d’un sous-programme. Exemples :
$arg = "fred";
# variable "globale"
$n = cube_root(27);
print "$arg thinks the root is $n\n";
fred thinks the root is 3
sub cube_root {
my $arg = shift;
# le nom n’importe pas
$arg **= 1/3;
return $arg;
}
Le my est simplement un modi?cateur sur quelque chose que vous pourriez affecter. Donc lorsque vous affectez les variable dans sa
liste d’arguments, le my ne change pas le fait que ces variables soient vues comme un scalaire ou un tableau. Donc
my ($foo) = <STDIN>;
# FAUX ?
my @FOO = <STDIN>;
les deux fournissent un contexte de liste à la partie droite, tandis que
my $foo = <STDIN>;
fournit un contexte scalaire. Mais ce qui suit ne déclare qu’une seule variable :
my $foo, $bar = 1;
# FAUX
Cela a le même effet que
my $foo;
$bar = 1;
55

6.2. DESCRIPTION
perlsub
La variable déclarée n’est pas introduite (n’est pas visible) avant la ?n de l’instruction courante. Ainsi,
my $x = $x;
peut être utilisé pour initialiser une nouvelle variable $x avec la valeur de l’ancienne $x, et l’expression
my $x = 123 and $x == 123
est fausse à moins que l’ancienne variable $x ait la valeur 123.
Les portées lexicales de structures de contrôle ne sont pas précisément liées aux accolades qui délimitent le bloc qu’elles contrôlent ;
les expressions de contrôle font aussi partie de cette portée. Ainsi, dans la boucle
while (my $line =<>) {
$line = lc $line;
} continue {
print $line;
}
la portée de $line s’étend à partir de sa déclaration et sur tout le reste de la boucle (y compris la clause continue), mais pas au-delà.
De façon similaire, dans la conditionnelle
if ((my $answer = <STDIN>) =~ /^yes$/i) {
user_agrees();
} elsif ($answer =~ /^no$/i) {
user_disagrees();
} else {
chomp $answer;
die "’$answer’ is neither ’yes’ nor ’no’";
}
la portée de $answer s’étend à partir de sa déclaration et sur tout le reste de la conditionnelle, y compris les clauses elsif et else,
s’il y en a, mais pas au-delà.
Rien du texte qui précède ne s’applique aux modi?cateurs if/unless et while/until ajoutés à d’autres instructions simples. De
tels modi?cateurs ne sont pas des structures de contrôle et n’ont pas d’effets sur la portée.
La boucle foreach a pour défaut de donner une portée dynamiquement a sa variable d’index à la manière de local. Toutefois, si la
variable d’index est pré?xée par le mot-clé my, ou s’il existe déjà un lexical ayant ce nom dans la porté, alors un nouveau lexical est
créé à la place. Ainsi dans la boucle
for my $i (1, 2, 3) {
some_function();
}
la portée de $i s’étend jusqu’à la ?n de la boucle, rendant la valeur de $i inaccessible dans some_function().
Certains utilisateurs pourraient désirer encourager l’usage de variables à portée lexicale. Comme aide pour intercepter les utilisations
implicites de variables de paquetage, qui sont toujours globales, si vous dites
use strict ’vars’;
alors toute variable mentionnée à partir de là jusqu’à la ?n du bloc doit soit se référer à une variable lexicale, soit être prédéclarée via
our ou use vars, soit encore être totalement quali?ée avec le nom du paquetage. Autrement, une erreur de compilation se produit.
Un bloc interne pourrait contrer ceci par no strict ’vars’.
Un my a un effet à la fois à la compilation et lors de l’exécution. Lors de la compilation, le compilateur le remarque. La principale
utilité de ceci est de faire taire use strict ’vars’, mais c’est aussi essentiel pour la génération de fermetures telle que détaillée
dans le manuel perlref. L’initialisation effective est toutefois retardée jusqu’à l’exécution, de façon à ce qu’elle soit exécutée au
moment approprié, par exemple à chaque fois qu’une boucle traversée.
Les variables déclarées avec my ne font pas partie d’un paquetage et ne sont par conséquent jamais totalement quali?ée avec le nom
du paquetage. En particulier, vous n’avez pas le droit d’essayer de rendre lexicale une variable de paquetage (ou toute autre variable
globale) :
my $pack::var;
# ERREUR ! Syntaxe Illégale
my $_;
# aussi illégal (pour le moment)
56

6.2. DESCRIPTION
perlsub
En fait, une variable dynamique (aussi connue sous le nom de variable de paquetage ou variable globale) est toujours accessible en
utilisant la notation totalement quali?ée :: même lorsqu’un lexical de même nom est lui aussi visible :
package main;
local $x = 10;
my
$x = 20;
print "$x and $::x\n";
Ceci af?chera 20 et 10.
Vous pouvez déclarer les variables my dans la portée extrême d’un ?chier pour cacher tous ces identifants du monde extérieur à ce
?chier. Cela est similaire en esprit aux variables statiques de C quand elles sont utilisées au niveau du ?chier. Faire cela avec un
sous-programme requiert l’usage d’une fermeture (une fonction anonyme qui accède aux lexicaux qui l’entourent). Si vous voulez
créer un sous-programme privé qui ne peut pas être appelé en-dehors de ce bloc, il peut déclarer une variable lexicale conenant une
référence anonyme de sous-programme :
my $secret_version = ’1.001-beta’;
my $secret_sub = sub { print $secret_version };
&$secret_sub();
Tant que la référence n’est jamais renvoyée par aucune fonction du module, aucun module extérieur ne peut voir le sous-
programme, car son nom n’est dans la table de symboles d’aucun paquetage. Souvenez-vous qu’il n’est jamais VRAIMENT appelé
$some_pack::secret_version ou quoi que ce soit ; c’est juste $secret_version, non quali?é et non quali?able.
Ceci ne fonctionne pas avec les méthodes d’objets, toutefois ; toutes les méthodes d’objets doivent se trouver dans la table de
symboles d’un paquetage quelconque pour être trouvées. Voir le titre Modèles de Fonctions dans le manuel perlref pour une méthode
permettant de contourner ceci.
6.2.2
Variables Privées Persistantes
Le fait qu’une variable lexicale ait une portée lexicale (aussi appelée statique) égale au bloc qui la contient, à l’eval, ou au FICHIER
do, ne veut pas dire que cela fonctionne à l’intérieur d’une fonction comme une variable statique en C. Cela marche normalement
plus comme une variable auto de C, mais avec un ramassage des miettes (garbage collection, NDT) implicite.
Contrairement aux variables locales en C ou en C++, les variables lexicales de Perl ne sont pas nécessairement recyclées juste parce
qu’on est sorti de leur portée. Si quelque chose de plus permanent est toujours conscient du lexical, il restera. Tant que quelque chose
d’autre fait référence au lexical, ce lexical ne sera pas libéré – ce qui est comme il se doit. Vous ne voudriez pas que la mémoire soit
libérée tant que vous n’avez pas ?ni de l’utiliser, ou gardée lorsque vous en avez terminé. Le ramasse-miette automatique s’occupe
de cela pour vous.
Ceci veut dire que vous pouvez passer en retour ou sauver des références à des variables lexicales, tandis que retourner un pointeur
sur un auto en C est une grave erreur. Cela nous donne aussi un moyen de simuler les variables statiques de fonctions C. Voici un
mécanisme donnant à une fonction des variables privées de portée lexicale ayant une durée de vie statique. Si vous désirez créer
quelque chose ressemblant aux vatiables statiques de C, entourez juste toute la fonction d’un niveau de bloc supplémentaire, et
mettez la variable statique hors de la fonction mais dans le bloc.
{
my $secret_val = 0;
sub gimme_another {
return ++$secret_val;
}
}
# $secret_val devient désormais impossible à atteindre pour le
# monde extérieur, mais garde sa valeur entre deux appels à
# gimme_another
Si cette fonction est chargée par require ou use depuis un ?chier séparé, alors cela marchera probablement très bien. Si tout se
trouve dans le programme principal, vous devrez vous arranger pour que le my soit exécuté tôt, soit en mettant tout le bloc avant votre
programme principal, ou, de préférence, en plaçant simplement un sous-programme BEGIN autour de lui pour vous assurer qu’il soit
exécutée avant que votre programme ne démarre :
sub BEGIN {
my $secret_val = 0;
sub gimme_another {
return ++$secret_val;
}
}
57

6.2. DESCRIPTION
perlsub
Voir le titre Constructeurs et Destructeurs de Paquetage dans le manuel perlmod au sujet des fonctions mises en oeuvre de façon
spéciale, BEGIN, CHECK, INIT et END.
S’ils sont déclarés au niveau de la plus grande portée (celle du ?chier), alors les lexicaux fonctionnent un peu comme les variables
statiques de ?chier en C. Ils sont disponibles pour toutes les fonctions déclarées en dessous d’eux dans le même ?chier, mais sont
inaccessibles hors du ?chier. Cette stratégie est parfois utilisé dans les modules pour créer des variables privées que la totalité du
module peut voir.
6.2.3
Valeurs Temporaires via local()
AVERTISSEMENT : En général, vous devriez utiliser my au lieu de local, parce que c’est plus rapide et plus sûr. Des exceptions
à cela incluent les variables globales de ponctuation, les handles de ?chier et les formats, et la manipulation directe de la table de
symboles de Perl elle-même. Les variables de format utilisent toutefois souvent local, tout comme les autres variables dont la valeur
courante doit être visible par les sous-programmes appelés.
Synopsis :
local $foo;
# déclare $foo locale dynamiquement
local (@wid, %get);
# déclare une liste de variables locales
local $foo = "flurp";
# déclare $foo dynamique, et l’initialise
local @oof = @bar;
# déclare @oof dynamique, et l’initialise
local *FH;
# rend locales $FH, @FH, %FH, &FH
local *merlyn = *randal;
# maintenant $merlyn est vraiment $randal, plus
#
@merlyn est vraiment @randal, etc
local *merlyn = ’randal’;
# MÊME CHOSE : ’randal’ est promu *randal
local *merlyn = \$randal;
# alias juste $merlyn, pas @merlyn etc
Un local() modi?e ses variables listées pour qu’elle soient "locales" au bloc courant, à l’eval, ou au FICHIER do – et à tout
sous-programme appelé depuis l’intérieur de ce bloc
. Un local() donne juste des valeurs temporaires aux variables globales (au
paquetage). Il ne crée pas une variable locale. Ceci est connu sous le nom de portée dynamique. La portée lexicale est créé par my,
qui fonctionne plus comme les déclarations auto de C.
Si plus d’une variable est donnée à local, elles doivent être placées entre parenthèses. Tous les éléments listés doivent être des
lvalues légales. Cet opérateur fonctionne en sauvegardant les valeurs courantes de ces variables dans sa liste d’arguments sur une
pile cachée et les restaure à la sortie du bloc, du sous-programme ou de l’eval. Ceci veut dire que les sous-programmes appelés
peuvent aussi référencer les variables locales, mais pas les globales. La liste d’arguments peut être affectée si l’on veut, ce qui vous
permet d’initialiser vos variables locales (si aucun initialiseur n’est donné pour une variable locale particulière, elle est créée avec la
valeur indé?nie). C’est couramment utilisé pour nommer les paramètres d’un sous-programme. Exemples :
for $i ( 0 .. 9 ) {
$digits{$i} = $i;
}
# présume que cette fonction utilise le hachage global %digits
parse_num();
# on ajoute maintenant temporairement au hachage %digits
if ($base12) {
# (NOTE : on ne prétend pas que ce soit efficace !)
local %digits
= (%digits, ’t’ => 10, ’e’ => 11);
parse_num();
# parse_num obtient ce nouveau %digits !
}
# l’ancien %digits est restauré ici
Puisque local est une commande réalisée lors de l’exécution, elle est exécutée chaque fois que l’on travers une boucle (Au relecteur :
exécution - exécutéé, bof). Dans les versions de Perl antérieures à la 5.0, ceci consommait chaque fois un peu plus de place sur la
pile jusqu’à la sortie de la boucle. Perl récupère désormais cette place à chaque fois, mais il est toujours plus ef?cace de déclarer vos
variables hors de la boucle.
Un local est simplement un modi?cateur d’une expression donnant une lvalue. Lorsque vous affectez une variable localisée, le
local ne change pas selon que sa liste est vue comme un scalaire ou un tableau. Donc
local($foo) = <STDIN>;
local @FOO = <STDIN>;
58

6.2. DESCRIPTION
perlsub
fournissent tous les deux un contexte de liste à la partie droite, tandis que
local $foo = <STDIN>;
fournit un contexte scalaire.
Une note sur local() et les types composés est nécessaire. Quelque chose comme local(%foo) fonctionne en plaçant temporaire-
ment un hachage tout neuf dans la table des symboles. L’ancien hachage est mis de côté, mais est caché "derrière" le nouveau.
Ceci signi?e que l’ancienne variable est complètement invisible via la table des symboles (i.e. l’entrée de hachage dans le typeglob
*foo) pendant toute la durée de la portée dynamique dans laquelle le local() a été rencontré. Cela a pour effet de permettre
d’occulter temporairement toute magie sur les types composés. Par exemple, ce qui suit altèrera brièvement un hachage lié à une
autre implémentation :
tie %ahash, ’APackage’;
[ ]
{
local %ahash;
tie %ahash, ’BPackage’;
[.. le code appelé verra %ahash lié à ’BPackage’..]
{
local %ahash;
[..%ahash est une hachage normal (non lié) ici..]
}
}
[..%ahash revient à sa nature liée initiale..]
Autre exemple, une implémentation personnelle de %ENV pourrait avoir l’air de ceci :
{
local %ENV;
tie %ENV, ’MyOwnEnv’;
[..faites vos propres manipulations fantaisistes de %ENV ici..]
}
[..comportement normal de %ENV ici..]
Il vaut aussi la peine de prendre un moment pour expliquer ce qui se passe lorsque vous localisez un membre d’un type composé
(i.e. un élément de tableau ou de hachage). Dans ce cas, l’élément est localisé par son nom. Cela veut dire que lorsque la portée du
local() se termine, la valeur sauvée sera restaurée dans l’élément du hachage dont la clé a été nommée dans le local(), ou dans
l’élément du tableau dont l’index a été nommé dans le local(). Si cet élément a été effacé pendant que le local() faisait effet (e.g.
par un delete() dans un hachage ou un shift() d’un tableau), il reprendra vie, étendant potentiellement un tableau et remplissant
les éléments intermédiaires avec undef. Par exemple, si vous dites
%hash = ( ’This’ => ’is’, ’a’ => ’test’ );
@ary
= ( 0..5 );
{
local($ary[5]) = 6;
local($hash{’a’}) = ’drill’;
while (my $e = pop(@ary)) {
print "$e . . .\n";
last unless $e > 3;
}
if (@ary) {
$hash{’only a’} = ’test’;
delete $hash{’a’};
}
}
print join(’ ’, map { "$_ $hash{$_}" } sort keys %hash),".\n";
print "The array has ",scalar(@ary)," elements: ",
join(’, ’, map { defined $_ ? $_ : ’undef’ } @ary),"\n";
Perl af?chera
59

6.2. DESCRIPTION
perlsub
6 . . .
4 . . .
3 . . .
This is a test only a test.
The array has 6 elements: 0, 1, 2, undef, undef, 5
Le comportement de local() sur des membres inexistants de types composites est sujet à changements à l’avenir.
6.2.4
Lvalue subroutines
AVERTISSEMENT : les sous-programmes en partie gauche sont encore expérimentaux et leur implémentation est sujette à chan-
gements dans les futures versions de Perl.
Il est possible de retourner une valeur modi?able depuis un sous-programme. Pour ce faire, vous devez déclarer que le sous-
programme retourne une lvalue.
my $val;
sub canmod : lvalue {
$val;
}
sub nomod {
$val;
}
canmod() = 5;
# affecte $val
nomod()
= 5;
# ERREUR
Le contexte scalaire ou de liste pour le sous-programme et la partie droite de l’affectation est déterminé comme si l’appel au sous-
programme était remplacé par un scalaire. Par exemple, si l’on considère :
data(2,3) = get_data(3,4);
Les deux sous-programmes sont appelées ici dans un contexte scalaire, tandis que dans :
(data(2,3)) = get_data(3,4);
et dans :
(data(2),data(3)) = get_data(3,4);
tous les sous-programmes sont appelés dans un contexte de liste.
L’implémentation actuelle ne permet pas le renvoit direct de tableaux ou de hachages par les sous-programmes en partie gauche.
Vous pouvez retourner une référence à la place. Cette restriction pourrait être levée à l’avenir.
6.2.5
Passage d’Entrées de Table de Symbole (typeglobs)
AVERTISSEMENT : le mécanisme décrit dans cette section était à l’origine la seule façon de simuler un passage par référence
dans les anciennes versions de Perl. Même si cela fonctionne toujours très bien dans les version modernes, le nouveau mécanisme
de référencement est généralement plus facile à utiliser. Voir plus bas.]
Parfois, vous ne voulez pas passer la valeur d’un tableau à un sous-programme mais plutôt son nom, pour que le sous-programme
puisse modi?er sa copie globale plutôt que de travailler sur une copie locale. En perl, vous pouvez vous référer à tous les objets
d’un nom particulier en pré?xant ce nom par une étoile : *foo. Cela est souvent connu sous le nom de "typeglob", car l’étoile
devant peut être conçue comme un caractère générique correspondant à tous les drôles de caractères pré?xant les variables et les
sous-programmes et le reste.
Lorsqu’il est évalué, le typeglob produit une valeur scalaire qui représente tous les objets portant ce nom, y compris tous les handles
de ?chiers, les formats, ou les sous-programmes. Quand on l’affecte, le nom mentionné se réfère alors à la valeur * qui lui a été
affectée, quelle qu’elle soit. Exemple :
60

6.2. DESCRIPTION
perlsub
sub doubleary {
local(*someary) = @_;
foreach $elem (@someary) {
$elem *= 2;
}
}
doubleary(*foo);
doubleary(*bar);
Les scalaires sont déjà passés par référence, vous pouvez donc modi?er les arguments scalaires sans utiliser ce mécanisme en vous
référant explicitement à $_[0], etc. Vous pouvez modi?er tous les éléments d’un tableau en passant tous les éléments comme des
scalaires, mais vous devez utiliser le mécanisme * (ou le mécanisme de référencement équivalent) pour effectuer des push, des pop,
ou changer la taille d’un tableau. Il sera certainement plus rapide de passer le typeglob (ou la référence).
Même si vous ne voulez pas modi?er un tableau, ce mécanisme est utile pour passer des tableaux multiples dans une seule LIST,
car normalement le mécanisme LIST fusionnera toutes les valeurs de tableaux et vous ne pourrez plus en extraire les tableaux
individuels. Pour plus de détails sur les typeglobs, voir le titre Typeglobs et Handles de Fichiers dans le manuel perldata.
6.2.6
Quand faut-il encore utiliser local()
Malgré l’existence de my, il y a encore trois endroits où l’opérateur local brille toujours. En fait, en ces trois endroits, vous devez
utiliser local à la place de my.
1. 1. Vous avez besoin de donner une valeur temporaire à une variable globale, en particulier $_.
Les variables globales, comme @ARGV ou les variables de ponctuation, doivent être localisées avec local(). Ce bloc lit dans
/etc/motd, et le découpe en morceaux, séparés par des lignes de signes égal, qui sont placés dans @Fields.
{
local @ARGV = ("/etc/motd");
local $/ = undef;
local $_ = <>;
@Fields = split /^\s*=+\s*$/;
}
Il est important en particulier de localiser $_ dans toute routine qui l’affecte. Surveillez les affectations implicites dans les
conditionnelles while.
2. 2. Vous avez besoin de créer un handle de ?chier ou de répertoire local, ou une fonction locale.
Une fonction ayant besoin de son propre handle de ?chier doit utiliser local() sur le typeglob complet. Ceci peut être utilisé
pour créer de nouvelles entrées dans la table des symboles :
sub ioqueue {
local
(*READER, *WRITER);
# pas my !
pipe
(READER,
WRITER);
or die "pipe: $!";
return (*READER, *WRITER);
}
($head, $tail) = ioqueue();
Voir le module Symbol pour une façon de créer des entrées de table de symboles anonymes.
Puisque l’affectation d’une référence à un typeglob crée un alias, ceci peut être utilisé pour créer ce qui est effectivement une
fonction locale, ou au moins un alias local.
{
local *grow = \&shrink; # seulement jusqu’à la fin de
# l’existence de ce bloc
grow();
# appelle en fait shrink()
move();
# si move() grandit, il rétrécit
# aussi
}
grow();
# récupère le vrai grow()
Voir le titre Modèles de Fonctions dans le manuel perlref pour plus de détails sur la manipulation des fonctions par leur nom
de cette manière.
61

6.2. DESCRIPTION
perlsub
3. 3. Vous voulez changer temporairement un seul élément d’un tableau ou d’un hachage.
Vous pouvez localiser juste un élément d’un aggrégat. Habituellement, cela est fait dynamiquement :
{
local $SIG{INT} = ’IGNORE’;
funct();
# impossible à interrompre
}
# la possibilité d’interrompre est restaurée ici
Mais cela fonctionne aussi sur les aggrégats déclarés lexicalement. Avant la version 5.005, cette opération pouvait parfois mal
se conduire.
6.2.7
Passage par Référence
Si vous voulez passer plus d’un tableau ou d’un hachage à une fonction – ou les renvoyer depuis elle – de façon qu’ils gardent leur
intégrité, vous allez devoir alors utiliser un passage par référence explicite. Avant de faire cela, vous avez besoin de comprendre les
références telles qu’elles sont détaillées dans le manuel perlref. Cette section n’aura peut-être pas beaucoup de sens pour vous sans
cela.
Voici quelques exemples simples. Tout d’abord, passons plusieurs tableaux à une fonction puis faisons-lui faire des pop sur eux, et
retourner une nouvelle liste de tous leurs derniers éléments :
@tailings = popmany ( \@a, \@b, \@c, \@d );
sub popmany {
my $aref;
my @retlist = ();
foreach $aref ( @_ ) {
push @retlist, pop @$aref;
}
return @retlist;
}
Voici comment vous pourriez écrire une fonction retournant une liste des clés apparaissant dans tous les hachages qu’on lui passe :
@common = inter( \%foo, \%bar, \%joe );
sub inter {
my ($k, $href, %seen); # locals
foreach $href (@_) {
while ( $k = each %$href ) {
$seen{$k}++;
}
}
return grep { $seen{$_} == @_ } keys %seen;
}
Jusque là, nous utilisons juste le mécanisme normal de retour d’une liste. Que se passe-t-il si vous voulez passer ou retourner un
hachage ? Eh bien, si vous n’utilisez que l’un d’entre eux, ou si vous ne voyez pas d’inconvénient à ce qu’ils soient concaténés, alors
la convention d’appel normale est valable, même si elle coûte un peu cher.
C’est ici que les gens commencent à avoir des problèmes :
(@a, @b) = func(@c, @d);
ou
(%a, %b) = func(%c, %d);
Cette syntaxe ne fonctionnera tout simplement pas. Elle dé?nit juste @a ou %a et vide @b ou %b. De plus, la fonction n’a pas obtenu
deux tableaux ou hachages séparés : elle a eu une longue liste dans @_, comme toujours.
Si vous pouvez vous arranger pour que tout le monde règle cela par des références, cela fait du code plus propre, même s’il n’est pas
très joli à regarder (phrase louche, NDT). Voici une fonction qui prend deux références de tableau comme arguments et renvoit les
deux éléments de tableau dans l’ordre du nombre d’éléments qu’ils contiennent :
62

6.2. DESCRIPTION
perlsub
($aref, $bref) = func(\@c, \@d);
print "@$aref has more than @$bref\n";
sub func {
my ($cref, $dref) = @_;
if (@$cref > @$dref) {
return ($cref, $dref);
} else {
return ($dref, $cref);
}
}
Il s’avère en fait que vous pouvez aussi faire ceci :
(*a, *b) = func(\@c, \@d);
print "@a has more than @b\n";
sub func {
local (*c, *d) = @_;
if (@c > @d) {
return (\@c, \@d);
} else {
return (\@d, \@c);
}
}
Ici nous utilisons les typeglobs pour faire un aliasing de la table des symboles. C’est un peu subtile, toutefois, et en plus cela ne
fonctionnera pas si vous utilisez des variables my, puisque seules les variables globales (et les locales en fait) sont dans la table des
symboles.
Si vous passez des handles de ?chiers, vous pouvez habituellement juste utiliser le typeglob tout seul, comme *STDOUT, mais les
références de typeglobs fonctionnent aussi. Par exemple :
splutter(\*STDOUT);
sub splutter {
my $fh = shift;
print $fh "her um well a hmmm\n";
}
$rec = get_rec(\*STDIN);
sub get_rec {
my $fh = shift;
return scalar <$fh>;
}
Si vous comptez générer de nouveau handles de ?chiers, vous pourriez faire ceci. Faites attention de renvoyer juste le *FH tout seul,
et pas sa référence.
sub openit {
my $path = shift;
local *FH;
return open (FH, $path) ? *FH : undef;
}
6.2.8
Prototypes
Perl supporte une sorte de véri?cation des arguments très limitée lors de la compilation, en utilisant le prototypage de fonction. Si
vous déclarez
sub mypush (\@@)
63

6.2. DESCRIPTION
perlsub
alors mypush() prendra ses arguments exactement comme push() le fait. La declaration de la fonction doit être visible au moment de
la compilation. Le prototype affecte seulement l’interprétation des appels nouveau style de la fonction, où le nouveau style est dé?ni
comme n’utilisant pas le caractère &. En d’autres termes, si vous l’appelez comme une fonction intégrée, alors elle se comportera
comme une fonction intégrée. Si vous l’appelez comme un sous-programme à l’ancienne mode, alors elle se comportera comme un
sous-programme à l’ancienne. La conséquence naturelle de cette règle est que les prototypes n’ont pas d’in?uence sur les références
de sous-programmes comme \&foo ou sur les appels de sous-programmes indirects comme &{$subref} ou $subref->().
Les appels de méthode ne sont pas non plus in?uencés par les prototypes, car la fonction qui doit être appelée est indéterminée au
moment de la compilation, puisque le code exact appelé dépend de l’héritage.
Puisque l’intention de cette caractéristique est principalement de vous laisser dé?nir des sous-programmes qui fonctionnent comme
des commandes intégrées, voici des prototypes pour quelques autres fonctions qui se compilent presque exactement comme les
fonctions intégrées correspondantes.
Déclarées en tant que
Appelé comme
sub mylink ($$)
mylink $old, $new
sub myvec ($$$)
myvec $var, $offset, 1
sub myindex ($$;$)
myindex &getstring, "substr"
sub mysyswrite ($$$;$)
mysyswrite $buf, 0, length($buf) - $off, $off
sub myreverse (@)
myreverse $a, $b, $c
sub myjoin ($@)
myjoin ":", $a, $b, $c
sub mypop (\@)
mypop @array
sub mysplice (\@$$@)
mysplice @array, @array, 0, @pushme
sub mykeys (\%)
mykeys %{$hashref}
sub myopen (*;$)
myopen HANDLE, $name
sub mypipe (**)
mypipe READHANDLE, WRITEHANDLE
sub mygrep (&@)
mygrep { /foo/ } $a, $b, $c
sub myrand ($)
myrand 42
sub mytime ()
mytime
Tout caractère de prototype précédé d’une barre oblique inverse représente un véritable argument qui doit absolument commencer par
ce caractère. La valeur passée comme partie de @_ sera une référence au véritable argument passé dans l’appel du sous-programme,
obtenue en appliquant \ à cet argument.
Les caractères de prototype non précédés d’une barre oblique inverse ont une signi?cation spéciale. Tout @ ou % sans barre oblique
inverse mange les arguments restants, et force un contexte de liste. Un argument représenté par $ force un contexte scalaire. Un &
requiert un sous-programme anonyme, qui, s’il est passé comme premier argument, ne requiert pas le mot-clé "sub" ni une virgule
après lui. Un * permet au sous-programme d’accepter un bareword, une constante, une expression scalaire, un typeglob, ou une
référence à un typeglob à cet emplacement. La valeur sera disponible pour le sous-programme soit comme un simple scalaire, soit
(dans les deux derniers cas) comme une référence au typeglob. Si vous désirez toujours convertir de tels arguments en référence de
typeglob, utilisez Symbol::qualify_to_ref() ainsi :
use Symbol ’qualify_to_ref’;
sub foo (*) {
my $fh = qualify_to_ref(shift, caller);

}
Un point-virgule sépare les arguments obligatoires des arguments optionnels. Il est redondant devant @ ou %, qui engloutissent tout
le reste.
Notez comment les trois derniers exemples dans la table ci-dessus sont traités spécialement par l’analyseur. mygrep() est compilé
comme un véritable opérateur de liste, myrand() comme un véritable opérateur unaire avec une précédence unaire identique à celle
de rand(), et mytime() est vraiment sans arguments, tout comme time(). C’est-à-dire que si vous dites
mytime +2;
Vous obtiendrez mytime() + 2, et pas mytime(2), qui est la façon dont cela serait analysé sans prototype.
Ce qui est intéressant avec & est que vous pouvez générer une nouvelle syntaxe grâce à lui, pourvu qu’il soit en position initiale :
64

6.2. DESCRIPTION
perlsub
sub try (&@) {
my($try,$catch) = @_;
eval { &$try };
if ($@) {
local $_ = $@;
&$catch;
}
}
sub catch (&) { $_[0] }
try {
die "phooey";
} catch {
/phooey/ and print "unphooey\n";
};
Cela af?che "unphooey" (Oui, il y a toujours des problèmes non résolus à propos de la visibilité de @_. J’ignore cette question
pour le moment (Mais notez que si nous donnons une portée lexicale à @_, ces sous-programmes anonymes peuvent agir comme des
fermetures  (Mince, est-ce que ceci sonne un peu lispien ? (Peu importe))).
Et voici une réimplémentation de l’opérateur grep de Perl :
sub mygrep (&@) {
my $code = shift;
my @result;
foreach $_ (@_) {
push(@result, $_) if &$code;
}
@result;
}
Certaines gens préféreraient des prototypes pleinement alphanumériques. Les caractères alphanumériques ont intentionnellement été
laissés hors des prototypes expressément dans le but d’ajouter un jour futur des paremètres formels nommés. Le principal objectif du
mécanisme actuel est de laisser les programmeurs de modules fournir de meilleurs diagnostics à leurs utilisateurs. Larry estime que
la notation est bien compréhensible pour les programmeurs Perl, et que cela n’interfèrera pas notablement avec le coeur du module,
ni ne le rendra plus dif?cile à lire. Le bruit sur la ligne est visuellement encapsulé dans une petite pilule facile à avaler.
Il est probablement meilleur de prototyper les nouvelles fonctions, et de ne pas prototyper rétrospectivement les anciennes. C’est
parce que vous devez être particulièrement précautionneux avec les exigences silencieuses de la différence entre les contextes de
liste et les contextes scalaires. Par exemple, si vous décidez qu’une fonction devrait prendre juste un paramètre, comme ceci :
sub func ($) {
my $n = shift;
print "you gave me $n\n";
}
et que quelqu’un l’a appelée avec un tableau ou une expression retournant une liste :
func(@foo);
func( split /:/ );
Alors vous venez juste de fournir un scalar automatique devant leurs arguments, ce qui peut être plus que surprenant. L’ancien
@foo qui avait l’habitude de ne contenir qu’une chose n’entre plus. À la place, func() se voit maintenant passer un 1 ; c’est-à-dire
le nombre d’éléments dans @foo. Et le split se voit appelé dans un contexte scalaire et commence à gribouiller dans votre liste de
paramètres @_. Aïe !
Tout ceci est très puissant, bien sûr, et devrait être utilisé uniquement avec modération pour rendre le monde meilleur.
6.2.9
Fonctions Constantes
Les fonctions ayant un prototype égal à () sont des candidates potentielles à l’insertion en ligne (inlining, NDT). Si le résultat après
optimisation et repliement des constantes est soit une constante soir un scalaire de portée lexicale n’ayant pas d’autre référence, alors
il sera utilisé à la place des appels à la fonction faits sans &. Les appels réalisés en utilisant & ne sont jamais insérés en ligne (Voir
 pour une façon aisée de déclarer la plupart des constantes).
Les fonctions suivantes seraient toutes insérées en ligne :
65

6.2. DESCRIPTION
perlsub
sub pi ()
{ 3.14159 }
# Pas exact, mais proche.
sub PI ()
{ 4 * atan2 1, 1 }
# Aussi exact qu’il
# puisse être, et
# inséré en ligne aussi !
sub ST_DEV ()
{ 0 }
sub ST_INO ()
{ 1 }
sub FLAG_FOO ()
{ 1 << 8 }
sub FLAG_BAR ()
{ 1 << 9 }
sub FLAG_MASK ()
{ FLAG_FOO | FLAG_BAR }
sub OPT_BAZ ()
{ not (0x1B58 & FLAG_MASK) }
sub BAZ_VAL () {
if (OPT_BAZ) {
return 23;
}
else {
return 42;
}
}
sub N () { int(BAZ_VAL) / 3 }
BEGIN {
my $prod = 1;
for (1..N) { $prod *= $_ }
sub N_FACTORIAL () { $prod }
}
Si vous redé?nissez un sous-programmes qui pouvait être inséré en ligne, vous obtiendrez un avertissement formel (vous pouvez
utiliser cet avertissement pour déterminer si un sous-programme particulier est considéré comme constant ou pas). L’avertissement
est considéré comme suf?samment sévère pour ne pas être optionnel, car les invocations précédemment compilées de la fonction
utiliseront toujours l’ancienne valeur de cette fonction. Si vous avez besoin de pouvoir redé?nir le sous-programme, vous devez vous
assurer qu’il n’est pas inséré en ligne, soit en abandonnant le prototype () (ce qui change la sémantique de l’appel, donc prenez
garde), soit en contrecarrant le mécanisme d’insertion d’une autre façon, comme par exemple
sub not_inlined () {
23 if $];
}
6.2.10
Surcharges des Fonctions Prédé?nies
Beaucoup de fonctions prédé?nies peuvent être surchargées, même si cela ne devrait être essayé qu’occasionnellement et pour une
bonne raison. Typiquement, cela pourrait être réalisé par un paquetage essayant d’émuler une fonctionnalité prédé?nie manquante
sur un système non Unix.
La surcharge ne peut être réalisée qu’en important le nom depuis un module – la prédéclaration ordinaire n’est pas suf?sante.
Toutefois, le pragma use subs vous laisse, dans les faits, prédéclarer les sous-programmes via la syntaxe d’importation, et ces noms
peuvent ensuite surcharger ceux qui sont prédé?nis :
use subs ’chdir’, ’chroot’, ’chmod’, ’chown’;
chdir $somewhere;
sub chdir {   }
Pour se référer sans ambiguïté à la forme prédé?nie, on peut faire précéder le nom prédé?ni par le quali?cateur de paquetage spéciale
CORE::. Par exemple, le fait de dire CORE::open() se réfère toujours à la fonction prédé?nie open(), même si le paquetage courant
a importé d’ailleurs un quelconque autre sous-programme appelé &open(). Même si cela a l’air d’un appel de fonction normal, ce
n’en est pas un : vous ne pouvez pas en créer de référence, telle que celles que l’incorrect \&CORE::open pourrait en produire.
Les modules de bibliothèque ne devraient en général pas exporter de noms prédé?nis comme open ou chdir comme partie de leur
liste @EXPORT par défaut, car ceux-ci pourraient s’in?ltrer dans l’espace de noms de quelqu’un d’autre et changer la sémantique de
façon inattendue. À la place, si le module ajoute ce nom à @EXPORT_OK, alors il est possible pour un utilisateur d’importer le nom
explicitement, mais pas implicitement. C’est-à-dire qu’il pourrait dire
66

6.2. DESCRIPTION
perlsub
use Module ’open’;
et cela importerait la surcharge open. Mais s’il disait
use Module;
il obtiendrait les importations par défaut sans les surcharges.
Le mécanisme précédent de surcharge des éléments prédé?nis est restreint, assez délibérément, au paquetage qui réclame l’im-
portation. Il existe une seconde méthode parfois applicable lorsque vous désirez surcharger partout une fonction prédé?nie, sans
tenir compte des frontières entre espaces de noms. Cela s’obtient en important un sous-programme dans l’espace de noms spé-
cial CORE::GLOBAL::. Voici un exemple qui remplace assez effrontément l’opérateur glob par quelque chose qui comprend les
expressions rationnelles.
package REGlob;
require Exporter;
@ISA = ’Exporter’;
@EXPORT_OK = ’glob’;
sub import {
my $pkg = shift;
return unless @_;
my $sym = shift;
my $where = ($sym =~ s/^GLOBAL_// ? ’CORE::GLOBAL’ : caller(0));
$pkg->export($where, $sym, @_);
}
sub glob {
my $pat = shift;
my @got;
local *D;
if (opendir D, ’.’) {
@got = grep /$pat/, readdir D;
closedir D;
}
return @got;
}
1;
Et voici comment on pourrait en (ab)user :
#use REGlob ’GLOBAL_glob’;
# surcharge glob() dans TOUS les
# espaces de noms
package Foo;
use REGlob ’glob’;
# surcharge glob() dans Foo::
# seulement
print for <^[a-z_]+\.pm\$>;
# montre tous les modules pragmatiques
Le commentaire initial montre un exemple arti?ciel, voire même dangereux. En surchargeant glob globalement, vous forceriez le
nouveau (et subversif) comportement de l’opérateur glob pour tous les espaces de noms, sans la complète coopération des modules
qui possèdent ces espaces de noms, et sans qu’ils en aient même connaissance. Naturellement, ceci doit être fait avec d’extrêmes
précautions – si jamais cela doit être fait.
L’exemple REGlob ci-dessus n’implémente pas tous le support nécessaires pour surcharger proprement l’opérateur glob de perl.
La fonction intégrée glob a des comportements différents selon qu’elle apparaît dans un contexte scalaire ou un contexte de lites,
mais ce n’est pas le cas de notre REGlob. En fait, beaucoup de fonctions prédé?nies de perl ont de tels comportements sensibles au
contexte, et ceux-ci doivent être supportés de façon adéquate par une surcharge correctement écrite. Pour un exemple pleinement
fonctionnel de surcharge de glob, étudiez l’implémentation de File::DosGlob dans la bibliothèque standard.
67

6.2. DESCRIPTION
perlsub
6.2.11
Autochargement
Si vous appelez un sous-programme qui n’est pas dé?ni, vous obtenez ordinairement une erreur fatale immédiate se plaignant que
le sous-programme n’existe pas (De même pour les sous-programmes utilisés comme méthodes, lorsque la méthode n’existe dans
aucune classe de base du paquetage de la classe). Toutefois, si un sous-programme AUTOLOAD est dé?ni dans le paquetage ou dans
les paquetages utilisés pour localiser le sous-programme originel, alors ce sous-programme AUTOLOAD est appelé avec les arguments
qui auraient été passés au sous-programme originel. Le nom pleinement quali?é du sous-programme originel apparaît magiquement
dans la variable globale $AUTOLOAD du même paquetage que la routine AUTOLOAD. Le nom n’est pas passé comme un argument
ordinaire parce que, euh, eh bien, juste parce que, c’est pour ça
La plupart des routines AUTOLOAD chargent une dé?nition du sous-programme requis en utilisant eval(), puis l’exécutent en utilisant
une forme spéciale de goto() qui efface la routine AUTOLOAD de la pile sans laisser de traces (Voir le module standard AutoLoader
pour un exemple). Mais une routine AUTOLOAD peut aussi juste émuler la routine et ne jamais la dé?nir. Par exemple, supposons
qu’une fonction non encore dé?nie doive juste appeler system avec ces arguments. Tout ce que vous feriez est ceci :
sub AUTOLOAD {
my $program = $AUTOLOAD;
$program =~ s/.*:://;
system($program, @_);
}
date();
who(’am’, ’i’);
ls(’-l’);
En fait, si vous prédéclarez les fonctions que vous désirez appeler de cette façon, vous n’avez mêmes pas besoin des parenthèses :
use subs qw(date who ls);
date;
who "am", "i";
ls -l;
Un exemple plus complet de ceci est le module Shell standard, qui peut traiter des appels indé?nis à des sous-programmes comme
des appels de programmes externes.
Des mécanismes sont disponibles pour aider les auteurs de modules à découper les modules en ?chiers autochargeables. Voir le
module standard AutoLoader décrit dans le manuel AutoLoader et dans le manuel AutoSplit, les modules standards SelfLoader dans
le manuel SelfLoader, et le document expliquant comment ajouter des fonctions C au code Perl dans le manuel perlxs.
6.2.12
Attributs de Sous-Programme
Une déclaration ou une dé?nition de sous-programme peut contenir une liste d’attributs qui lui sont associés. Si une telle liste est
présente, elle est découpée aux espaces et aux deux-points et traitée comme si un use attributes avait été rencontré. Voir le
manuel attributes pour plus de détails sur les différents attributs actuellement supportés. Contrairement aux limitations de l’use
attrs obsolète, la syntaxe sub : ATTRLIST fonctionne pour associer les attributs à une prédéclaration, et pas seulement dans la
dé?nition de sous-programme.
Les attributs doivent être des identi?ants simples valides (sans aucune ponctuation à part le caractère "_"). Ils peuvent être suivis
d’une liste de paramètres, qui n’est contrôlée que pour voir si ses parenthèses (’(’,’)’) sont correctement imbriquées.
Exemples de syntaxe valide (même si les attributs sont inconnus) :
sub fnord (&\%) : switch(10,foo(7,3))
:
expensive ;
sub plugh () : Ugly(’\(") :Bad ;
sub xyzzy : _5x5 {   }
Exemples de syntaxe invalide :
sub fnord : switch(10,foo() ; # () non équilibrées
sub snoid : Ugly(’(’) ;
# () non équilibrées
sub xyzzy : 5x5 ;
# "5x5" n’est pas un identifiant valide
sub plugh : Y2::north ;
# "Y2::north" n’est pas un identifiant simple
sub snurt : foo + bar ;
# "+" n’est pas un deux-points ni une espace
La liste d’attributs est passée comme une liste de chaînes constantes au code qui les associe au sous-programme. En particulier, le
second exemple de syntaxe valide ci-dessus à cette allure en termes d’analyse syntaxique et d’invocation :
use attributes __PACKAGE__, \&plugh, q[Ugly(’\(")], ’Bad’;
Pour plus de détails sur les listes d’attributs et leur manipulation, voir le manuel attributes.
68

6.3. VOIR AUSSI
perlsub
6.3
VOIR AUSSI
Voir le manuel perlref pour plus de détails sur les références et les fermetures. Voir le manuel perlxs pour apprendre à appeler des
sous-programmes en C depuis Perl. Voir le manuel perlembed pour apprendre à appeler des sous-programmes Perl en C. Voir le
manuel perlmod pour apprendre à emballer vos fonctions dans des ?chiers séparés. Voir le manuel perlmodlib pour apprendre quels
modules de bibliothèques sont fournis en standard sur votre système. Voir le manuel perltoot pour apprendre à faire des appels à des
méthodes objet.
6.4
VERSION FRANÇAISE
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.0. Pour en savoir plus concernant ces traductions,
consultez ;.
6.5
TRADUCTION
Roland Trique <>
6.6
RELECTURE
Personne pour l’instant.
69

Chapitre 7
perlfunc – Fonctions Perl prédé?nies
Fonctions Perl prédé?nies
7.1
DESCRIPTION
Les fonctions de cette section peuvent être utilisées en tant que termes dans une expression. Elles se séparent en deux catégories
principales : les opérateurs de listes et les opérateurs unaires nommés. Ceux-ci diffèrent dans leurs relations de priorité avec la
virgule qui les suit. (Cf. la table de priorité dans le manuel perlop.) Les opérateurs de liste prennent plusieurs arguments alors que
les opérateurs unaires n’en prennent jamais plus d’un. Une virgule termine alors l’argument d’un opérateur unaire mais sépare les
arguments d’un opérateur de liste. Un opérateur unaire fournit en général un contexte scalaire à son argument, alors qu’un opérateur
de liste fournit un contexte, soit scalaire, soit de liste, pour ses arguments. S’il propose les deux, les arguments scalaires seront les
premiers et la liste d’arguments suivra. (Notez qu’il ne peut y avoir qu’une seule liste d’arguments.) Par exemple, splice() a trois
arguments scalaires suivis d’une liste alors que gethostbyname() a quatre arguments scalaires.
Dans la description syntaxique qui suit, les opérateurs de liste qui attendent une liste (et fournissent un contexte de liste pour les
éléments de cette liste) ont pour argument LISTE. Une telle liste peut-être constituer de toute combinaison de valeurs d’arguments
scalaires ou de listes ; les valeurs de listes seront incluses dans la liste comme si chaque élément individuel était interpolé à cet
emplacement de la liste, formant ainsi la valeur d’une longue liste unidimensionnelle. Les éléments de LISTE doivent être séparés
par des virgules.
Toute fonction de la liste ci-dessous peut être utilisée avec ou sans parenthèses autour de ses arguments. (Les descriptions syntaxiques
les omettent) Si vous utilisez les parenthèses, la simple (mais parfois surprenante) règle est la suivante : ça RESSEMBLE à une
fonction, donc c’EST une fonction, et la priorité importe peu. Sinon, c’est un opérateur de liste ou un opérateur unaire et la priorité
a son importance. Les espaces entre la fonction et les parenthèses ne comptent pas, vous devez donc faire parfois très attention :
print 1+2+4;
# affiche 7.
print(1+2) + 4;
# affiche 3.
print (1+2)+4;
# affiche aussi 3 !
print +(1+2)+4;
# affiche 7.
print ((1+2)+4);
# affiche 7.
Si vous exécutez Perl avec l’option -w, vous pourrez en être averti. Par exemple, la troisième ligne ci-dessus génère :
print ( ) interpreted as function at - line 1.
Useless use of integer addition in void context at - line 1.
Quelques rares fonctions ne prennent aucun argument et ne sont donc ni des opérateurs unaires ni des opérateurs de liste. Cela inclut
des fonctions telles que time et endpwent. Par exemple, time+86_400 signi?e toujours time() + 86_400.
Pour les fonctions qui peuvent être utilisées dans un contexte scalaire ou de liste, une erreur non fatale est généralement indiquée
dans un contexte scalaire en retournant la valeur indé?nie, et dans un contexte de liste en retournant la liste nulle.
Rappelez-vous de l’importante règle suivante : il n’y a aucune règle qui lie le comportement d’une expression dans un contexte de
liste à son comportement dans un contexte scalaire, et réciproquement. Cela peut générer deux résultats complètement différents.
Chaque opérateur et chaque fonction choisit le type de valeur qui semble le plus approprié de retourner dans un contexte scalaire.
Certains opérateurs retournent la longueur de la liste qui aurait été retournée dans un contexte de liste. D’autres opérateurs retournent
la première valeur. D’autres encore retournent la dernière valeur. D’autres en?n retournent le nombre d’opérations réussies. En
général, ils font ce que vous souhaitez, à moins que vous ne vouliez de la consistance.
70

7.1. DESCRIPTION
perlfunc
Un tableau nommé en contexte scalaire est assez différent de ce qui apparaîtrait au premier coup d’oeil comme une liste dans un
contexte scalaire. Vous ne pouvez pas transformer une liste comme (1,2,3) dans un contexte scalaire, car le compilateur connaît le
contexte à la compilation. Il générerait ici l’opérateur scalaire virgule, et non pas la version construction de liste de la virgule. Ce qui
signi?e que ça n’a jamais été considéré comme une liste avec laquelle travailler.
En général, les fonctions en Perl qui encapsulent les appels système du même nom (comme chown(2), fork(2), closedir(2), etc.)
retournent toutes vrai quand elles réussissent et undef sinon, comme c’est souvent mentionné ci-dessous. C’est différent des
interfaces C qui retournent -1 en cas d’erreur. Les exceptions à cette règle sont wait, waitpid() et syscall(). Les appels système
positionnent aussi la variable spéciale $! en cas d’erreur. Les autres fonctions ne le font pas, sauf de manière accidentelle.
7.1.1
Fonctions Perl par catégories
Voici les fonctions Perl (y compris ce qui ressemble à des fonctions, comme certains mots-clés et les opérateurs nommés) triées par
catégorie. Certaines fonctions apparaissent dans plusieurs catégories à la fois.
Fonctions liées aux SCALAIREs ou aux chaînes de caractères
chomp, chop, chr, crypt, hex, index, lc, lcfirst, length, oct, ord, pack, q/CHAINE/, qq/CHAINE/, reverse, rindex,
sprintf, substr, tr///, uc, ucfirst, y///
Expressions rationnelles et reconnaissances de motifs
m//, pos, quotemeta, s///, split, study, qr//
Fonctions numériques
abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt, srand
Fonctions liées aux véritables @TABLEAUx
pop, push, shift, splice, unshift
Fonctions aux listes de données
grep, join, map, qw/CHAINE/, reverse, sort, unpack
Fonctions liées aux véritables %TABLEs de hachage
delete, each, exists, keys, values
Fonctions d’entrée/sortie
binmode, close, closedir, dbmclose, dbmopen, die, eof, fileno, flock, format, getc, print, printf, read, readdir,
rewinddir, seek, seekdir, select, syscall, sysread, sysseek, syswrite, tell, telldir, truncate, warn, write
Fonctions pour données de longueur ?xe ou pour enregistrements
pack, read, syscall, sysread, syswrite, unpack, vec
Fonctions de descripteurs de ?chiers, de ?chiers ou de répertoires
-X, chdir, chmod, chown, chroot, fcntl, glob, ioctl, link, lstat, mkdir, open, opendir, readlink, rename, rmdir,
stat, symlink, umask, unlink, utime
Mots-clés liés au contrôle d’exécution de votre programme perl
caller, continue, die, do, dump, eval, exit, goto, last, next, redo, return, sub, wantarray
Mots-clés liés à la portée
caller, import, local, my, our, package, use
Fonctions diverses
defined, dump, eval, formline, local, my, reset, scalar, undef, wantarray
Fonctions de gestion des processus et des groupes de processus
alarm, exec, fork, getpgrp, getppid, getpriority, kill, pipe, qx/CHAINE/, setpgrp, setpriority, sleep, system,
times, wait, waitpid
Mots-clés liés aux modules perl
do, import, no, package, require, use
Mots-clés liés aux classes et à la programmation orientée objet
bless, dbmclose, dbmopen, package, ref, tie, tied, untie, use
Fonctions de bas niveau liées aux sockets
accept, bind, connect, getpeername, getsockname, getsockopt, listen, recv, send, setsockopt, shutdown, socket,
socketpair
Fonctions IPC (communication inter-processus) System V
msgctl, msgget, msgrcv, msgsnd, semctl, semget, semop, shmctl, shmget, shmread, shmwrite
71

7.1. DESCRIPTION
perlfunc
Manipulation des informations sur les utilisateurs et les groupes
endgrent, endhostent, endnetent, endpwent, getgrent, getgrgid, getgrnam, getlogin, getpwent, getpwnam,
getpwuid, setgrent, setpwent
Manipulation des informations du réseau
endprotoent, endservent, gethostbyaddr, gethostbyname, gethostent, getnetbyaddr, getnetbyname, getnetent,
getprotobyname, getprotobynumber, getprotoent, getservbyname, getservbyport, getservent, sethostent,
setnetent, setprotoent, setservent
Fonction de date et heure
gmtime, localtime, time, times
Nouvelles fonctions de perl5
abs, bless, chomp, chr, exists, formline, glob, import, lc, lcfirst, map, my, no, prototype, qx, qw, readline,
readpipe, ref, sub*, sysopen, tie, tied, uc, ucfirst, untie, use
* - sub était un mot-clé dans perl4, mais dans perl5 c’est un opérateur qui peut être utilisé au sein d’expressions.
Fonctions obsolètes en perl5
dbmclose, dbmopen
7.1.2
Portabilité
Perl est né sur Unix et peut, par conséquent, accéder à tous les appels systèmes Unix courants. Dans des environnements non-Unix,
les fonctionnalités de certains appels systèmes Unix peuvent manquer ou différer sur certains détails. Les fonctions Perl affectées
par cela sont :
-X, binmode, chmod, chown, chroot, crypt, dbmclose, dbmopen, dump, endgrent, endhostent, endnetent, endprotoent,
endpwent, endservent, exec, fcntl, flock, fork, getgrent, getgrgid, gethostent, getlogin, getnetbyaddr,
getnetbyname, getnetent, getppid, getpgrp, getpriority, getprotobynumber, getprotoent, getpwent, getpwnam,
getpwuid, getservbyport, getservent, getsockopt, glob, ioctl, kill, link, lstat, msgctl, msgget, msgrcv, msgsnd,
open, pipe, readlink, rename, select, semctl, semget, semop, setgrent, sethostent, setnetent, setpgrp, setpriority,
setprotoent, setpwent, setservent, setsockopt, shmctl, shmget, shmread, shmwrite, socket, socketpair, stat, symlink,
syscall, sysopen, system, times, truncate, umask, unlink, utime, wait, waitpid
Pour de plus amples détails sur la portabilité de ces fonctions, voir le manuel perlport et toutes les documentations disponibles
spéci?ques à la plate-forme considérée.
7.1.3
Fonctions Perl par ordre alphabétique
-X DESCRIPTEUR
-X EXPR
-X
Un test de ?chier où X est une des lettres présentées ci-dessous. Cet opérateur unaire prend soit un argument, soit un nom
de ?chier, soit un descripteur de ?chier, et teste le ?chier associé pour constater si quelque chose est véri?é à son sujet. Si
l’argument est omis, il teste $_, sauf -t qui teste STDIN. Sauf indication contraire, il retourne 1 pour VRAI et ” pour FAUX,
ou la valeur indé?nie (undef) si le ?chier n’existe pas. Malgré leurs noms originaux, leur priorité est la même que celle de tout
autre opérateur unaire nommé et l’argument peut-être mis de même entre parenthèses. L’opérateur peut être :
-r
Le fichier est en lecture par le uid/gid effectif.
-w
Le fichier est en écriture par le uid/gid effectif.
-x
Le fichier est exécutable par le uid/gid effectif.
-o
Le fichier appartient au uid effectif.
-R
Le fichier est en lecture par le uid/gid réel.
-W
Le fichier est en écriture par le uid/gid réel.
-X
Le fichier est exécutable par le uid/gid réel.
-O
Le fichier appartient au uid réel.
-e
Le fichier existe.
-z
Le fichier a une taille nulle.
-s
Le fichier n’a pas une taille nulle (retourne sa taille).
72

7.1. DESCRIPTION
perlfunc
-f
Le fichier est un fichier normal.
-d
Le fichier est un répertoire.
-l
Le fichier est un lien symbolique.
-p
Le fichier est un tube nommée (FIFO), ou le descripteur est un pipe.
-S
Le fichier est une socket.
-b
Le fichier est un fichier blocs spécial.
-c
Le fichier est un fichier caractères spécial.
-t
Le fichier est ouvert sur un tty.
-u
Le fichier a le bit setuid positionné.
-g
Le fichier a le bit setgid positionné.
-k
Le fichier a le sticky bit positionné.
-T
Le fichier est un fichier texte ASCII.
-B
Le fichier est un fichier binaire (le contraire de -T).
-M
L’âge du fichier en jours quand le script a été lancé.
-A
Idem pour le dernier accès au fichier.
-C
Idem pour le dernier changement de l’inode du fichier.
Exemple :
while (<>) {
chop;
next unless -f $_;
# ignore les fichiers spéciaux
#
}
L’interprétation des opérateurs de permission sur le ?chier -r, -R, -w, -W, -x, et -X est uniquement basée sur le mode du
?chier et les uids/gids de l’utilisateur. En fait, il peut y avoir d’autres raisons pour lesquelles vous ne pouvez pas lire, écrire
ou exécuter le ?chier. Par exemple, le contrôle d’accès aux systèmes de ?chiers réseau (NFS), les listes de contrôles d’accès
(ACL), les systèmes de ?chiers en lecture seule et les formats d’exécutable non reconnus.
Notez aussi que, pour le super-utilisateur, -r, -R, -w, et -W retournent toujours 1, et -x ainsi que -X retournent 1 si l’un des bits
d’exécution est positionné dans le mode. Les scripts exécutés par le super-utilisateur peuvent donc nécessiter un appel stat()
pour déterminer exactement les droits du ?chier ou alors effectuer un changement temporaire d’uid.
Si vous utilisez les ACL (listes de contrôles d’accès), il existe un pragma appelé filetest qui peut produire des résultats
plus précis que les informations minimales des bits de permissions fournies par stat(). Lorsque vous faites use filetest
’access’, les tests sur ?chiers susnommés utiliseront les appels systèmes de la famille access(). Notez aussi que dans ce cas,
les tests -x et -X peuvent retourner VRAI même si aucun bit d’exécution n’est positionné (que ce soit les bits normaux ou
ceux des ACLs). Ce comportement étrange est dû à la dé?nition des appels systèmes sous-jacents. Lisez la documentation du
pragma filetest pour de plus amples informations.
Notez que -s/a/b/ n’effectue pas une substitution négative. Toutefois, écrire -exp($foo) fonctionne toujours comme prévu
– seule une lettre isolée après un tiret est interprétée comme un test de ?chier.
Les tests -T et -B fonctionnent de la manière suivante. Le premier bloc du ?chier est examiné, à la recherche de caractères
spéciaux tels que des codes de contrôle ou des octets avec un bit de poids fort. Si trop de caractères spéciaux (> 30 %) sont
rencontrés, c’est un ?chier -B, sinon c’est un ?chier -T. De plus, tout ?chier contenant un octet nul dans le premier bloc est
considéré comme binaire. Si -T ou -B est utilisé sur un descripteur de ?chier, le tampon stdio courant est examiné à la place
du premier bloc. -T et -B retournent tous les deux VRAI sur un ?chier nul, ou une ?n de ?chier s’il s’agit d’un descripteur.
Comme vous devez lire un ?chier pour effectuer le test -T, la plupart du temps, vous devriez d’abord utiliser un -f sur le
?chier, comme dans next unless -f $file && -T $file.
Si le descripteur spécial, constitué d’un seul underscore (N.d.T. : caractère souligné), est fourni comme argument d’un test de
?chier (ou aux opérateurs stat() et lstat()), alors c’est la structure stat du dernier ?chier traité par un test (ou opérateur)
qui est utilisée, épargnant ainsi un appel système. (Ceci ne fonctionne pas avec -t et n’oubliez pas que lstat() et -l laisseront
dans la structure stat des informations liées au ?chier symbolique et non au ?chier réel.) Exemple :
print "Can do.\n" if -r $a || -w _ || -x _;
stat($filename);
print "Readable\n" if -r _;
print "Writable\n" if -w _;
print "Executable\n" if -x _;
print "Setuid\n" if -u _;
print "Setgid\n" if -g _;
73

7.1. DESCRIPTION
perlfunc
print "Sticky\n" if -k _;
print "Text\n" if -T _;
print "Binary\n" if -B _;
abs VALEUR
abs
Retourne la valeur absolue de son argument. Si VALEUR est omis, utilise $_.
accept NOUVELLESOCKET,GENERIQUESOCKET
Accepte une connexion entrante de socket, tout comme l’appel système accept(2). Retourne l’adresse compacte en cas de
succès, FAUX sinon. Voir l’exemple de le titre Sockets : communication client/serveur dans le manuel perlipc.
Sur les systèmes qui supportent le drapeau fermeture-à-l-exécution (close-on-exec) sur les ?chiers, ce drapeau sera positionné
pour de nouveaux descripteurs de ?chier en fonction de la valeur de $ˆF. Voir le titre $ˆF dans le manuel perlvar.
alarm SECONDES
alarm
S’arrange pour qu’un SIGALRM soit délivrer au processus après que le nombre spéci?é de secondes se soient écoulées. Si
SECONDES est omis, la valeur de $_ est utilisée. (Sur certaines machines, malheureusement, le temps écoulé peut être jusqu’à
une seconde de plus que celui spéci?é, en fonction de la façon dont les secondes sont comptées.) Il n’est pas possible d’activer
plusieurs décompte temporel à la fois. Chaque appel annule le décompte précédent. La valeur 0 peut être fournie pour annuler
le décompte précédent sans en créer un nouveau. La valeur retournée est le temps restant de décompte précédent.
Pour des délais d’une précision inférieure à la seconde, vous pouvez utiliser soit la version Perl à quatre paramètres de select()
en laissant les trois premiers indé?nis soit l’interface syscall() de Perl pour accéder à setitimer(2) si votre système le
supporte. Le module CPAN Time::HiRes peut aussi s’avérer utile.
C’est souvent une erreur de mélanger des appels à alarm() avec des appels à sleep() (sleep peut-être implémenté via des
appels internes à alarm sur votre système.)
Si vous souhaitez utiliser alarm() pour contrôler la durée d’un appel système, il vous faut utiliser le couple eval()/die().
Vous ne pouvez pas compter sur l’alarme qui déclenche l’échec de l’appel système avec $! positionné à EINTR car Perl met en
place des descripteurs de signaux pour redémarrer ces appels sur certains systèmes. Utiliser eval()/die() fonctionne toujours
sous réserve de l’avertissement signalé dans le titre Signaux dans le manuel perlipc.
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # N.B. : \n obligatoire
alarm $timeout;
$nread = sysread SOCKET, $buffer, $size;
alarm 0;
};
if ($@) {
die unless $@ eq "alarm\n";
# propage des erreurs inattendues
# délai dépassé : time out
}
else {
# délai non dépassé
}
atan2 Y,X
Retourne l’arc-tangente de Y/X dans l’intervalle -PI à PI.
Pour l’opération tangente, vous pouvez utiliser la fonction POSIX::tan() ou la relation habituelle :
sub tan { sin($_[0]) / cos($_[0])
}
bind SOCKET,NOM
Associe une adresse réseau à une socket, tout comme l’appel système bind. Retourne VRAI en cas de succès, FAUX sinon.
NOM doit être une adresse compactée (par pack()) du type approprié pour la socket. Voir les exemples de le titre Sockets :
communication client/serveur dans le manuel perlipc.
binmode DESCRIPTEUR, DISCIPLINE
binmode DESCRIPTEUR
Positionne le ?chier pour être lu ou écrit en mode "binaire" ou en mode "texte" sur les systèmes d’exploitation qui font la
distinction entre ?chiers texte et binaire. Si DESCRIPTEUR est une expression, sa valeur est utilisée comme nom du descrip-
teur. DISCIPLINE peut être soit ":raw" pour le mode binaire soit ":crlf" pour le mode texte. Par défaut, DISCIPLINE vaut
":raw".
74

7.1. DESCRIPTION
perlfunc
binmode() doit être appelé après open() et avant toute opération d’entrée/sortie sur le descripteur de ?chier.
Sur de nombreux systèmes, binmode() n’a aucun effet pour l’instant mais dans le futur il sera étendu pour supporter des
disciplines d’entrée et de sortie dé?nies par l’utilisateur. Sur certains systèmes, binmode() est nécessaire lorsque vous travaillez
sur des ?chiers non textuels. Pour assurer la portabilité, c’est une bonne idée de toujours l’utiliser lorsque c’est approprié et
de ne jamais l’utiliser dans les autres cas.
En d’autres termes : indépendamment de la plate-forme, utilisez binmode() sur les ?chier binaires et n’utilisez pas binmode()
sur les ?chiers textes.
Le pragma open peut être utilisé pour ?xer une discipline par défaut. Voir le manuel open.
Le système d’exploitation, les pilotes de périphériques, les bibliothèques C et l’interpréteur de Perl coopèrent a?n de permettre
au programmeur de considérer une ?n de ligne comme un seul caractère (\n) et cela, indépendamment de sa représentation
externe. Sur la plupart des systèmes d’exploitation, la représentation utilisée par les ?chiers textes natifs correspond à la
représentation interne mais sur certaines plates-formes la représentation externe de \n est constituée de plus d’un caractère.
Mac OS et toutes les variantes d’UNIX utilisent un seul caractère pour représenter une ?n de ligne dans leur représentation
externe des textes (même si ce caractère unique n’est pas nécessairement le même sur chaque plate-forme). Par conséquent,
binmode() n’a aucun effet sur ces systèmes d’exploitation. Sur d’autres systèmes tels que VMS, MS-DOS et les différentes
versions de MS-Windows, votre programme voit un \n comme un simple \cJ mais ce qui est réellement stocké dans les ?chiers
textes est le couple de caractères \cM\cJ. Cela signi?e que, si vous n’utilisez pas binmode() sur ces systèmes, les séquences
\cM\cJ sur disque seront convertit en \n en entrée et que tous les \n produits par votre programme seront reconvertis en
\cM\cJ à la sortie. C’est ce que vous voulez pour les ?chiers textes mais cela peut être désastreux pour un ?chier binaire.
Autre conséquence de l’utilisation de binmode() (sur certains systèmes) : les marqueurs spéciaux de ?n de ?chiers seront vus
comme faisant partie du ?ux de données. Pour les systèmes de la famille Microsoft, cela signi?e que, si vos données binaires
contiennent un \cZ, le système d’entrée/sortie le considérera comme une ?n de ?chier à moins que vous n’utilisiez binmode().
binmode() est important non seulement pour les opérations readline() et print() mais aussi lorsque vous utilisez read(), seek(),
sysread(), syswrite() et tell() (voir le manuel perlport pour plus d’informations). Voir aussi $/ et $\ dans le manuel perlvar
pour savoir comment ?xer manuellement les séquences de ?n de lignes en entrée et en sortie.
bless REF,NOMCLASSE
bless REF
Cette fonction précise à la chose référencée par REF qu’elle est désormais un objet du paquetage NOMCLASSE – ou le
paquetage courant si aucun NOMCLASSE n’est spéci?é, ce qui est souvent le cas. Étant donné que l’appel à bless() est
souvent la dernière instruction d’un constructeur, cette fonction retourne la référence elle-même. Utilisez toujours la version
à deux arguments si la fonction effectuant la "bénédiction" bless() peut être héritée par une classe dérivée. Cf. le manuel
perltoot et le manuel perlobj pour de plus amples informations sur la bénédiction (et les bénédictions) d’objets.
Ne blessez des objets qu’avec des NOMCLASSEs mélangeant des majuscules et des minuscules. Les espaces de nommages
entièrement en minuscule sont réservés pour les pragmas Perl. Les types prédé?nis utilisent les noms entièrement en majuscule.
Donc, pour éviter toute confusion, vous devez éviter ces deux types de nommage. Soyez sûr que NOMCLASSE est une valeur
vraie.
Voir le titre Modules Perl dans le manuel perlmod.
caller EXPR
caller
Retourne le contexte de l’appel de subroutine courant. Dans un contexte scalaire, retourne le nom du paquetage de l’appelant,
s’il existe, c’est-à-dire si nous sommes dans une subroutine, un eval() ou un require(), et retourne la valeur indé?nie
(undef) sinon. En contexte de liste, retourne
($package, $filename, $line) = caller;
Avec EXPR, il retourne des informations supplémentaires que le débogueur utilise pour af?cher un historique de la pile. La
valeur de EXPR donne le nombre de contextes d’appels à examiner au-dessus de celui en cours.
($package, $filename, $line, $subroutine, $hasargs,
$wantarray, $evaltext, $is_require, $hints, $bitmask) = caller($i);
Ici, $subroutine peut être "(eval)" si le cadre n’est pas un appel de routine mais un eval(). Dans un tel cas, les éléments
supplémentaires $evaltext et $is_require sont positionnés : $is_require est vrai si le contexte est créé par un require ou
un use, $evaltext contient le texte de l’instruction eval EXPR. En particulier, pour une instruction eval BLOC, $filename
vaut "(eval)" mais $evaltext est indé?ni. (Notez aussi que chaque instruction use créée un contexte require à l’intérieur
d’un contexte eval EXPR.) Les valeurs de $hints et de $bitmask risquent de changer d’une version de Perl à une autre. Elles
n’ont donc aucun intérêt pour une utilisation externe.
De plus, s’il est appelé depuis le paquetage DB, caller retourne plus de détails : il affecte à la liste de variables @DB::args
les arguments avec lesquels la routine a été appelée.
75

7.1. DESCRIPTION
perlfunc
Prenez garde à l’optimiseur qui peut avoir optimisé des contextes d’appel avant que caller() ait une chance de récupérer
les informations. Ce qui signi?e que caller(N) pourrait ne pas retourner les informations concernant le contexte d’appel
que vous attendez, pour N > 1. En particulier, @DB::args peut contenir des informations relatives à un appel précédent de
caller().
chdir EXPR
Change le répertoire courant à EXPR, si c’est possible. Si EXPR est omis, change vers le répertoire spéci?é par la variable
$ENV{HOME} si elle est dé?nie; sinon c’est le répertoire spéci?é par la variable $ENV{LOGDIR} qui est utilisé. Retourne VRAI
en cas de succès, FAUX sinon. Cf. exemple de die().
chmod LISTE
Change les permissions d’une liste de ?chiers. Le premier élément de la liste doit être le mode numérique, qui devrait être un
nombre en octal et non une chaîne de chiffres en octal : 0644 est correct, mais pas ’0644’. Retourne le nombre de ?chiers dont
les permissions ont été changées avec succès. Voir aussi le titre oct dans ce document, si vous ne disposez que d’une chaîne de
chiffres.
$cnt = chmod 0755, ’foo’, ’bar’;
chmod 0755, @executables;
$mode = ’0644’; chmod $mode, ’foo’;
# !!! fixe le mode à
# --w----r-T
$mode = ’0644’; chmod oct($mode), ’foo’; # ceci est mieux
$mode = 0644;
chmod $mode, ’foo’;
# cela est le meilleur
Vous pouvez aussi importer les constantes symboliques S_I* du module Fcntl :
use Fcntl ’:mode’;
chmod S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, @executables;
# Identique au chmod 0755 de l’exemple précédent.
chomp VARIABLE
chomp LISTE
chomp
Cette version sûre de le titre chop dans ce document supprime toute ?n de ligne correspondant à la valeur courante de $/
(connue aussi sous le nom de $INPUT_RECORD_SEPARATOR dans le module English). Elle retourne le nombre total de
caractères effacés de tous ses arguments. Elle est souvent utilisée pour effacer le saut de ligne de la ?n d’une entrée quand vous
vous souciez que l’enregistrement ?nal pourrait ne pas avoir ce saut de ligne. En mode paragraphe ($/ = ""), elle efface tous
les sauts de ligne à la ?n de la chaîne de caractères. En mode «slurp» ($/ = undef) ou en mode enregistrement de taille ?xe
($/ est une référence vers un entier ou similaire, voir le manuel perlvar) chomp() ne supprime rien du tout. Si VARIABLE est
omis, elle tronque $_. Exemple :
while (<>) {
chomp;
# évite le \n du dernier champ
@array = split(/:/);

}
Vous pouvez en fait tronquer tout ce qui est une lvalue, y compris les affectations :
chomp($cwd = ‘pwd‘);
chomp($answer = <STDIN>);
Si vous tronquez une liste, chaque élément est tronqué et le nombre total de caractères effacés est retourné.
chop VARIABLE
chop LISTE
chop
Efface le dernier caractère d’une chaîne et le retourne. Cet opérateur est utilisé pour effacer le saut de ligne de la ?n d’une
entrée car il est plus ef?cace que s/\n// étant donné qu’il ne scanne ni ne copie la chaîne. Si VARIABLE est omis, tronque
$_. Exemple :
while (<>) {
chop;
# évite \n du dernier champ
@array = split(/:/);
#
}
76

7.1. DESCRIPTION
perlfunc
Vous pouvez en fait tronquer tout ce qui est une lvalue, y compris les affectations :
chop($cwd = ‘pwd‘);
chop($answer = <STDIN>);
Si vous tronquez une liste, chaque élément est tronqué. Seul la valeur du dernier chop() est retournée.
Notez que chop() retourne le dernier caractère. Pour retourner tout sauf le dernier caractère, utilisez substr($string, 0,
-1).
chown LISTE
Change le propriétaire (et le groupe) d’une liste de ?chiers. Les deux premiers éléments de la liste doivent être, dans l’ordre,
les uid et gid numériques. Une valeur -1 à l’une de ces positions est interprétée par la plupart des systèmes comme une valeur
à ne pas modi?er. Retourne le nombre de ?chiers modi?és avec succès.
$cnt = chown $uid, $gid, ’foo’, ’bar’;
chown $uid, $gid, @filenames;
Voici un exemple qui cherche les uid non numériques dans le ?chier de mots de passe :
print "User: ";
chop($user = <STDIN>);
print "Files: ";
chop($pattern = <STDIN>);
($login,$pass,$uid,$gid) = getpwnam($user)
or die "$user not in passwd file";
@ary = glob($pattern);
# expansion des noms de fichiers
chown $uid, $gid, @ary;
Sur la plupart des systèmes, vous n’êtes pas autorisé à changer le propriétaire d’un ?chier à moins d’être le super-utilisateur,
même si avez la possibilité de changer un groupe en l’un de vos groupes secondaires. Sur les systèmes non sécurisés, ces
restrictions peuvent être moindres, mais ceci n’est pas une hypothèse portable. Sur les systèmes POSIX, vous pouvez détecter
cette condition de la manière suivant :
use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
$can_chown_giveaway = not sysconf(_PC_CHOWN_RESTRICTED);
chr NOMBRE
chr
Retourne le caractère représenté par ce NOMBRE dans le jeu de caractères. Par exemple, chr(65) est "A" en ASCII ou
Unicode et chr(0x263a) est un visage réjoui en Unicode (mais uniquement dans la portée d’un use utf8). Pour la fonction
réciproque, utilisez le titre ord dans ce document. Voir le manuel utf8 pour en savoir plus sur Unicode.
Si NOMBRE est omis, utilise $_.
chroot FICHIER
chroot
Cet opérateur fonctionne comme l’appel système du même nom : il fait du répertoire spéci?é le nouveau répertoire racine pour
tous les chemins commençant par un "/" utilisés par votre processus et ses enfants. (Ceci n’affecte pas le répertoire courant
qui reste inchangé.) Pour des raisons de sécurité, cet appel est restreint au super-utilisateur. Si FICHIER est omis, effectue un
chroot() sur $_.
close DESCRIPTEUR
close
Ferme le ?chier ou le tube associé au descripteur de ?chier, retournant VRAI seulement si stdio a réussi à purger ses tampons
et à fermer le descripteur système du ?chier. Ferme le descripteur courant si l’argument est omis.
Vous n’avez pas à fermer le DESCRIPTEUR si vous allez immédiatement refaire un open() sur celui-ci, car open() le
fermera pour vous. (voir open().) Toutefois, un close() explicite sur un ?chier d’entrée réinitialise le compteur de ligne ($.)
alors que la fermeture implicite par un open() ne le fait pas.
Si le descripteur vient d’un tube ouvert, close() va de plus retourner FAUX si un des autres appels systèmes impliqués échoue
ou si le programme se termine avec un statut non nul. (Si le seul problème rencontré est une terminaison de programme non
nulle, $! sera à 0.) De même, la fermeture d’un tube attend que le programme exécuté sur le tube soit achevé, au cas où vous
souhaiteriez voir la sortie du tube après coup, et positionne implicitement la valeur du statut de sortie de la commande dans
$?.
77

7.1. DESCRIPTION
perlfunc
La fermeture prématurée d’une extrémité de lecture d’un tube (c’est à dire avant que le processus qui écrit à l’autre extrémité
l’est fermé) aura pour conséquence l’envoi d’un signal SIGPIPE au processus écrivain. Si l’autre extrémité n’est pas prévue
pour gérer cela, soyez sûr d’avoir lu toutes les données avant de fermer le tube.
Exemple :
open(OUTPUT, ’|sort >foo’)
# tube vers sort
or die "Can’t start sort: $!";
#
# imprime des trucs sur la sortie
close OUTPUT
# attend la fin de sort
or warn $! ? "Error closing sort pipe: $!"
: "Exit status $? from sort";
open(INPUT, ’foo’)
# recupere les resultats de sort
or die "Can’t open ’foo’ for input: $!";
Le DESCRIPTEUR peut être une expression dont la valeur peut être utilisée en tant que descripteur indirect, habituellement
le véritable nom du descripteur.
closedir REPDESCRIPTEUR
Ferme un répertoire ouvert par opendir() et retourne le résultat de cet appel système.
Le REPDESCRIPTEUR peut être une expression dont la valeur peut être utilisée comme un descripteur indirect de répertoire,
habituellement le véritable nom du descripteur de répertoire.
connect SOCKET,NOM
Tente une connexion sur une socket distante, tout comme le fait l’appel système du même nom. Retourne VRAI en cas de
succès, FAUX sinon. Le NOM doit être une adresse compactée (par pack()) du type approprié correspondant à la socket. Voir
les exemples de le titre Sockets : communication Client/Serveur dans le manuel perlipc.
continue BLOC
En fait, c’est une instruction de contrôle d’exécution plutôt qu’une fonction. S’il y a un BLOC continue rattaché à un BLOC
(typiquement dans un while ou un foreach), il est toujours exécuté juste avant le test à évaluer à nouveau, tout comme la
troisième partie d’une boucle for en C. Il peut donc être utilisé pour incrémenter une variable de boucle, même si la boucle a
été continuée par l’instruction next (qui est similaire à l’instruction continue en C).
last, next, ou redo peuvent apparaître dans un bloc continue. last et redo vont se comporter comme si ils avaient été
exécutés dans le bloc principal. De même pour next, mais comme il va exécuter un bloc continue, il peut s’avérer encore
plus divertissant.
while (EXPR) {
### redo vient toujours ici
do_something;
} continue {
### next vient toujours ici
do_something_else;
# puis retour au sommet pour revérifier EXPR
}
### last vient toujours ici
Omettre la section continue est sémantiquement équivalent à en utiliser une vide, de manière assez logique. Dans ce cas,
next retourne directement véri?er la condition au sommet de la boucle.
cos EXPR
Retourne le cosinus de EXPR (exprimé en radians). Si EXPR est omis, calcule le cosinus de $_.
Pour la fonction réciproque, vous pouvez utiliser la fonction Math:;Trig::acos() ou alors utiliser cette relation :
sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }
crypt TEXTE,SEL
Crypte une chaîne de caractères exactement comme la fonction crypt(3) de la bibliothèques C (en supposant que vous en avez
une version dont elle n’a pas été extirpée en tant que munition potentielle). Ceci peut s’avérer utile, entre autres choses, pour
véri?er le ?chier de mots de passe à la recherche de mots de passe bancals. Seuls les types portant un chapeau blanc devraient
faire ça.
Notez que crypt() est conçu pour être une fonction à sens unique, un peu comme les oeufs qu’on casse pour faire une
omelette. Il n’y a aucune fonction (connue) pour décrypter. Par conséquent, cette fonction n’est pas du tout utile pour de la
cryptographie. (Pour ça, voyez plutôt votre miroir CPAN le plus proche.)
78

7.1. DESCRIPTION
perlfunc
Pour véri?er une chaîne cryptée, vous devriez utiliser cette chaîne cryptée comme SEL (comme dans crypt($plain,
$crypted) eq $crypted). Cela permet à votre script de fonctionner aussi bien avec le crypt standard qu’avec des im-
plémentations plus exotiques. Lorsque vous choisissez un nouveau SEL constitué de deux caractères aléatoires, ces caractères
doivent provenir de l’ensemble [./0-9A-Za-z] (Exemple join ”, (’.’, ’/’, 0..9, ’A’..’Z’, ’a’..’z’)[rand
64, rand 64]).
Voici un exemple qui garantit que quiconque lance ce programme connaît son propre mot de passe :
$pwd = (getpwuid($<))[1];
$salt = substr($pwd, 0, 2);
system "stty -echo";
print "Password: ";
chop($word = <STDIN>);
print "\n";
system "stty echo";
if (crypt($word, $salt) ne $pwd) {
die "Sorry \n";
} else {
print "ok\n";
}
Bien évidemment, donner votre mot de passe à quiconque vous le demande est très peu recommandé.
La fonction crypt n’est pas utilisable pour chiffrer de grande quantité d’information déjà parce que vous ne pouvez pas
retrouver l’information initiale. Regardez les répertoires by-module/Crypt et by-module/PGP sur votre miroir CPAN préféré
pour y trouver des modules plus pratiques.
dbmclose HASH
[Cette fonction a été remplacée par la fonction untie().]
Rompt le lien entre un ?chier DBM et une table de hachage.
dbmopen HASH,DBNOM,MODE
[Cette fonction a été remplacée par la fonction tie().]
Cette fonction lie un ?chier dbm(3), ndbm(3), sdbm(3), gdbm(3), ou Berkeley DB à une table de hachage. HASH est le
nom de la table de hachage. (À la différence du open() normal, le premier argument n’est pas un descripteur de ?chier,
même s’il en a l’air). DBNOM est le nom de la base de données (sans l’extension .dir ou .pag, le cas échéant). Si la base de
données n’existe pas, elle est créée avec les droits spéci?és par MODE (et modi?és par umask). Si votre système supporte
uniquement les anciennes fonctions DBM, vous ne pouvez exécuter qu’un seul dbmopen() dans votre programme. Dans les
anciennes versions de Perl, si votre système n’avait ni DBM ni ndbm, l’appel à dbmopen() produisait une erreur fatale ; il
utilise maintenant sdbm(3).
Si vous n’avez pas les droits d’écriture sur le ?chier DBM, vous pouvez seulement lire les variables de la table de hachage,
vous ne pouvez pas y écrire. Si vous souhaitez tester si vous pouvez y écrire, faites un test sur le ?chier ou essayez d’écrire
une entrée bidon dans la table de hachage, à l’intérieur d’un eval(), qui interceptera l’erreur.
Notez que les fonctions telles que keys() et values() peuvent retourner des listes gigantesques si elles sont utilisées sur de
gros ?chiers DBM. Vous devriez préférer la fonction each() pour parcourir des ?chiers DBM volumineux. Exemple :
# imprime en sortie les index du fichier d’historiques
dbmopen(%HIST,’/usr/lib/news/history’,0666);
while (($key,$val) = each %HIST) {
print $key, ’ = ’, unpack(’L’,$val), "\n";
}
dbmclose(%HIST);
Voir aussi le titre AnyDBM_File dans ce document pour une description plus générale des avantages et inconvénients des
différentes approches dbm ainsi que le titre DB_File dans ce document pour une implémentation particulièrement riche.
Vous pouvez contrôler la bibliothèque DBM utilisé en chargeant cette bibliothèque avant l’appel à dbmopen() :
use DB_File;
dbmopen(%NS_Hist, "$ENV{HOME}")
or die "Can’t open netscape history file: $!";
de?ned EXPR
79

7.1. DESCRIPTION
perlfunc
de?ned
Retourne une valeur booléenne exprimant si EXPR a une valeur autre que la valeur indé?nie undef. Si EXPR est absent, $_
sera véri?ée de la sorte.
De nombreuses opérations retournent undef pour signaler un échec, la ?n d’un ?chier, une erreur système, une variable non
initialisée et d’autres conditions exceptionnelles. Cette fonction vous permet de distinguer undef des autres valeurs. (Un
simple test booléen ne distinguera pas undef, zéro, la chaîne de caractères vide et <"0">, qui représentent tous faux.) Notez
que puisque undef est un scalaire valide, sa présence n’indique pas nécessairement une condition exceptionnelle : pop()
retourne undef quand son argument est un tableau vide ou quand l’élément à retourner a la valeur undef.
Vous pouvez aussi utiliser defined(&func) pour véri?er si la subroutine &func a déjà été dé?nie. La valeur retournée ne sera
pas affectée par une déclaration préalable de &func.
L’utilisation de defined() sur des agrégats (tables de hachage et tableaux) est dépréciée. C’était utilisé pour savoir si de la
mémoire avait déjà été allouée pour cet agrégat. Ce comportement pourrait disparaître dans une future version de Perl. Vous
devriez utiliser un simple test de taille à la place :
if (@an_array) { print "has array elements\n" }
if (%a_hash)
{ print "has hash members\n"
}
Utilisé sur un élément de table de hachage, il vous indique si la valeur est dé?nie, mais pas si la clé existe dans la table. Utilisez
le titre exists dans ce document dans ce but.
Exemples :
print if defined $switch{’D’};
print "$val\n" while defined($val = pop(@ary));
die "Can’t readlink $sym: $!"
unless defined($value = readlink $sym);
sub foo { defined &$bar ? &$bar(@_) : die "No bar"; }
$debugging = 0 unless defined $debugging;
Note : de nombreuses personnes ont tendance à trop utiliser defined() et sont donc surprises de découvrir que le nombre 0
et "" (la chaîne de caractères vide) sont, en fait, des valeurs dé?nies. Par exemple, si vous écrivez :
"ab" =~ /a(.*)b/;
La recherche de motif réussit et $1 est dé?nie, malgré le fait qu’il ne correspond à "rien". Mais elle n’a pas véritablement
rien trouvé – elle a plutôt trouvé quelque chose qui s’est avéré être d’une longueur de 0 caractères. Tout ceci reste très loyal
et honnête. Quand une fonction retourne une valeur indé?nie, il est admis qu’elle ne pourrait pas vous donner une réponse
honnête. Vous devriez donc utiliser defined() uniquement lorsque vous vous posez des questions sur l’intégrité de ce que
vous tentez de faire. Sinon, une simple comparaison avec 0 ou "" est ce que vous voulez.
Voir aussi le titre undef dans ce document, le titre exists dans ce document, le titre ref dans ce document.
delete EXPR
À partir d’une expression EXPR qui spéci?e un élément ou un ensemble d’éléments (slice) d’une table de hachage ou d’un
tableau, supprime le(s) élément(s) spéci?é(s) de la table de hachage ou du tableau. Dans le cas d’un tableau, si les éléments
supprimés se trouvent à la ?n du tableau, la taille du tableau est réduite à l’indice le plus grand de tous les indices des éléments
restants qui donnent une valeur vraie lorsqu’on teste leur existence via exists() (ou 0 si aucun élément n’existe).
Retourne tous les éléments ainsi supprimés ou la valeur indé?nie (undef) si aucun élément n’a été supprimé. Supprimer des
éléments dans $ENV{} modi?e les variables d’environnement. Supprimer des éléments d’une table de hachage liée à un ?chier
DBM supprime ces éléments du ?chier. Supprimer des éléments d’une table de hachage ou d’un tableau lié ne retourne pas
nécessairement quelque chose.
Supprimer un élément d’un tableau réinitialise effectivement cet emplacement à sa valeur indé?nie initiale. En conséquence,
un test d’existence sur cet élément via exists() retournera faux. Notez bien que supprimer des éléments au milieu d’un tableau
ne décale pas vers le bas les indices des éléments suivants – utiliser splice() pour cela. Voir le titre exists dans ce document.
Le code suivant supprime (de manière inef?cace) toutes les valeurs de %HASH et de @TABLEAU :
foreach $key (keys %HASH) {
delete $HASH{$key};
}
foreach $index (0 .. $#TABLEAU) {
delete $TABLEAU[$index];
}
De même que le code suivant :
80

7.1. DESCRIPTION
perlfunc
delete @HASH{keys %HASH}
delete @TABLEAU[0 .. $#TABLEAU];
Ces deux méthodes restent toutefois beaucoup plus lentes que la simple assignation de la liste vide ou l’utilisation de undef()
sur %HASH ou @TABLEAU :
%HASH = ();
# vider complètement %HASH
undef %HASH;
# oublier que %HASH a existé
@TABLEAU = ();
# vider complètement @TABLEAU
undef @TABLEAU;
# oublier que @TABLEAU a existé
Notez que EXPR peut être arbitrairement compliquée tant que l’opération ?nale se réfère à un élément ou une partie d’une
table de hachage ou d’un tableau :
delete $ref->[$x][$y]{$key};
delete @{$ref->[$x][$y]}{$key1, $key2, @morekeys};
delete $ref->[$x][$y][$index];
delete @{$ref->[$x][$y]}[$index1, $index2, @moreindices];
die LISTE
En dehors d’un eval(), af?che les valeur de la LISTE sur STDERR et quitte avec la valeur actuelle de $! (numéro d’erreur
errno). Si $! est 0, sort avec la valeur ($? >> 8) (statut d’une ‘commande‘ entre simples apostrophes inverses). Si ($? >>
8) est 0, sort avec 255. A l’intérieur d’un eval(), le message d’erreur est mis dans $@ et le eval() s’achève sur la valeur
indé?nie. Ce qui fait de die() la façon de soulever une exception.
Exemples équivalents :
die "Can’t cd to spool: $!\n" unless chdir ’/usr/spool/news’;
chdir ’/usr/spool/news’ or die "Can’t cd to spool: $!\n"
Si la valeur de EXPR ne se termine pas par un saut de ligne, le numéro de la ligne actuelle du script et le numéro de la ligne
d’entrée (le cas échéant) sont aussi af?chés et un saut de ligne est ajouté. Notez que "le numéro de la ligne d’entrée" (mieux
connu sous le nom de "chunk") est dépendant de la notion de "ligne" courante et est disponible dans la variable spéciale $..
Voir le titre $/ dans le manuel perlvar et le titre $. dans le manuel perlvar.
Astuce : parfois, la concaténation de ", stopped" à votre message le rendra plus sensé lorsque la chaîne de caractères "at
foo line 123" sera ajoutée. Supposez que vous exécutiez le script "canasta".
die "/etc/games is no good";
die "/etc/games is no good, stopped";
va respectivement produire
/etc/games is no good at canasta line 123.
/etc/games is no good, stopped at canasta line 123.
Voir aussi exit() et warn() et le module Carp.
Si la LISTE est vide et que $@ contient déjà une valeur (typiquement provenant d’une évaluation précédente), cette valeur est
réutilisée après la concaténation de "\t propagated". Ceci est utile pour propager des exceptions :
eval {   };
die unless $@ =~ /Expected exception/;
Si $@ est vide, alors la chaîne de caractères "Died" est utilisée.
L’argument de die() peut aussi être une référence. Lorsque cela arrive à l’intérieur d’un eval() alors $@ contiendra cette réfé-
rence. Ce comportement autorise une implémentation plus élaborée de la gestion des exceptions utilisant des objets contenant
une description arbitraire de la nature de l’exception. Une telle utilisation est parfois préférable à la reconnaissance d’un motif
particulier par une expression rationnelle appliquée la valeur de $@. Voici un exemple :
eval {   ; die Some::Module::Exception->new( FOO => "bar" ) };
if ($@) {
if (ref($@) && UNIVERSAL::isa($@,"Some::Module::Exception")) {
# gestion de Some::Module::Exception
}
else {
# gestion de toutes les autres exceptions
}
}
81

7.1. DESCRIPTION
perlfunc
Étant donné que perl transformera en chaîne toutes les exceptions non captées avant de les af?cher, vous voudrez peut-être
surcharger l’opération de transformation en chaîne de tous vos objets représentant des exceptions. Regardez le manuel overload
pour faire cela.
Vous pouvez vous arranger pour qu’une subroutine (de callback) soit appelée juste après le die() en l’attachant à
$SIG{__DIE__}. La subroutine associée sera appelée avec le texte de l’erreur et peut changer le message de l’erreur, le
cas échéant, en appelant die() à nouveau. Voir le titre $SIG{expr} dans le manuel perlvar pour les détails sur l’assignation
des entrées de %SIG et §?? pour des exemples. Bien que cette fonctionnalité ait été conçue a?n d’être utilisée juste au mo-
ment où votre script se termine, ce n’est pas le cas – la subroutine attachée à $SIG{__DIE__} peut aussi être appelée lors de
l’eval()uation d’un bloc ou d’une chaîne ! Si vous voulez que votre subroutine ne fasse rien dans ce cas, utilisez :
die @_ if $^S;
comme première ligne de votre subroutine (Voir le titre $ˆS dans le manuel perlvar). Étant donné que cela peut engendrer des
choses étranges, ce comportement contre-intuitif devrait être changé dans une prochaine version.
do BLOC
Pas vraiment une fonction. Retourne la valeur de la dernière commande dans la suite de commandes contenues dans BLOC.
Lorsque modi?é par un modi?cateur de boucle, exécute le BLOC une fois avant le test de la condition de boucle. (Dans les
autres cas, le modi?cateur de boucle teste la condition d’abord.)
do BLOC n’est pas considéré comme une boucle et donc les instructions de contrôle de boucle next, last et redo ne peuvent
pas être utilisées pour quitter ou redémarrer le bloc. Voir le manuel perlsyn pour des stratégies alternatives.
do ROUTINE(LISTE)
Forme dépréciée d’appel de routine. Voir le manuel perlsub.
do EXPR
Utilise la valeur de EXPR comme nom de ?chier et exécute le contenu de ce ?chier en tant que script Perl. Son utilité première
est d’inclure les subroutines d’une bibliothèques de subroutines Perl.
do ’’;
est identique à
scalar eval ‘cat ‘;
sauf que c’est plus ef?cace et concis, qu’une trace du ?chier courant est gardée pour les messages d’erreur, que la recherche
du ?chier a lieu dans dans tous les répertoires de @INC et que, si le ?chier est trouvé, %INC est mis à jour. Voir le titre Noms
prédé?nis dans le manuel perlvar pour ces variables. De plus, les variables lexicales visibles lors de l’appel ne sont pas vues
par do NOMFICHIER alors qu’elle le sont par eval CHAINE. En revanche, dans les deux cas, le ?chier est retraité à chaque fois
que vous l’appeler ce qui n’est probablement pas ce que vous voudriez faire à l’intérieur d’une boucle.
Si do ne peut pas lire le ?chier, il retourne undef et assigne l’erreur à $!. Si do peut lire le ?chier mais non le compiler, il
retourne undef et assigne une message d’erreur à $@. Si le ?chier est compilé avec succès, do retourne la valeur de la dernière
expression évaluée.
Notez que l’inclusion de modules de bibliothèques est mieux faite par les opérateurs use() et require() qui effectuent aussi
une véri?cation automatique des erreurs et soulèvent une exception s’il y a le moindre problème.
Vous pourriez aimer utiliser do pour lire le ?chier de con?guration d’un programme. La véri?cation manuelle d’erreurs peut
être effectuer de la façon suivante :
# lecture des fichiers : d’abord le système puis l’utilisateur
for $file ("",
"$ENV{HOME}/.someprogrc") {
unless ($return = do $file) {
warn "couldn’t parse $file: $@" if $@;
warn "couldn’t do $file: $!"
unless defined $return;
warn "couldn’t run $file"
unless $return;
}
}
dump LABEL
Ceci provoque immédiatement la création de l’image mémoire du programme (core dump). Voir aussi l’option de ligne de
commande -u dans le manuel perlrun qui fait la même chose. À départ, ceci permet d’utiliser le programme undump (non
fourni) pour convertir votre image mémoire en un programme binaire exécutable après avoir initialisé toutes vos variables
au début du programme. Quand le nouveau binaire est exécuté, il va commencer par exécuter un goto LABEL (avec toutes
les restrictions dont souffre goto). Pensez-y comme un branchement goto avec l’intervention d’une image mémoire et une
réincarnation. Si LABEL est omis, relance le programme au début.
82

7.1. DESCRIPTION
perlfunc
ATTENTION : tout ?chier ouvert au moment de la copie ne sera PAS ouvert à nouveau quand le programme sera réincarné,
avec pour résultat une confusion possible sur la portion de Perl.
Cet opérateur est très largement obsolète, en partie parce qu’il est très dif?cile de convertir un ?chier d’image mémoire (core)
en exécutable mais aussi parce que le véritable compilateur perl-en-C l’a surpassé.
Si vous projeter d’utiliser le manuel dump pour augmenter la vitesse de votre programme, essayez donc du produire du pseudo-
code (ou bytecode) ou du C natif comme cela est décrit dans le manuel perlcc. Si vous essayez juste d’accélérer un script CGI,
regardez donc du côté de l’extension mod_perl de Apache ou de celui du module Fast::CGI sur CPAN. Vous pouvez aussi
envisager l’autochargement (autoloading ou sel?oading) qui donnera au moins la sensation que votre programme va plus vite.
each HASH
Appelé dans un contexte de liste, retourne une liste de deux éléments constituée de la clé et de la valeur du prochain élément
d’une table de hachage, de sorte que vous puissiez itérer sur celle-ci. Appelé dans un contexte scalaire, retourne uniquement
la clé de l’élément suivant de la table de hachage.
Les entrées sont apparemment retournées dans un ordre aléatoire. Cette ordre aléatoire réel pourrait changer dans les versions
futures de perl mais vous avez la garantie que cette ordre sera le même que vous utilisiez la fonction keys ou la fonction
values sur une même table de hachage (non modi?ée).
Quand la table de hachage est entièrement lue, un tableau nul est retourné dans un contexte de liste (qui, lorsqu’il est assigné,
produit une valeur FAUSSE 0), et undef dans un contexte scalaire. Le prochain appel à each après cela redémarrera une
nouvelle itération. Il y a un seul itérateur pour chaque table de hachage, partagé par tous les appels à each, keys ou values
du programme ; Il peut être réinitialiser en lisant tous les éléments de la table ou en évaluant keys HASH ou values HASH. Si
vous ajoutez ou supprimez des éléments d’une table de hachage pendant que vous itérez sur celle-ci, vous pourriez avoir des
entrées ignorées ou dupliquées, donc ne le faites pas.
Le code suivant af?che votre environnement comme le fait le programme printenv(1), mais dans un ordre différent :
while (($key,$value) = each %ENV) {
print "$key=$value\n";
}
Voir aussi keys() et values().
eof DESCRIPTEUR
eof ()
eof
Retourne 1 si la prochaine lecture sur un DESCRIPTEUR de ?chier va retourner une ?n de ?chier, ou si le DESCRIPTEUR
n’est pas ouvert. Le DESCRIPTEUR peut être une expression dont la valeur donne un véritable descripteur de ?chier. (Notez
que cette fonction lit en fait un caractère puis le retire comme ungetc(), elle n’est donc pas vraiment utile dans un contexte
interactif.) Ne faites pas de lecture sur un ?chier d’un terminal (ou d’appel à eof(DESCRIPTEUR) sur celui-ci) après qu’une
?n de ?chier soit atteinte. Les types de ?chiers comme les terminaux peuvent perdre la condition de ?n de ?chier si vous le
faites.
Un eof sans un argument utilise le dernier ?chier lu comme argument. Utiliser eof() avec des parenthèses vides est très
différent. Il se réfère alors au pseudo ?chier formé par les ?chiers listés sur la ligne de commande et lu par l’opérateur <>.
Puisque <> n’est pas explicitement ouvert comme l’est un descripteur de ?chier normal, l’utilisation de eof() avant celle de
<> déclenchera l’examen de @ARGV pour voir si une entrée est disponible.
Dans une boucle while (<>) eof(ARGV) ou eof peuvent être utilisée pour tester la ?n de CHAQUE ?chier alors que eof()
ne détectera que la ?n du tout dernier ?chier. Exemple :
# réinitialise le numérotage des lignes sur chaque fichier d’entrée
while (<>) {
next if /^\s*#/;
# saute les commentaires
print "$.\t$_";
} continue {
close ARGV
if eof;
# ce n’est pas eof() !
}
# insère des tirets juste avant la dernière ligne du dernier fichier
while (<>) {
if (eof()) {
# vérifie la fin du fichier courant
print "--------------\n";
close(ARGV);
# ferme ou s’arrête ; nécessaire en cas
# de lecture sur le terminal
}
print;
}
83

7.1. DESCRIPTION
perlfunc
Astuce pratique : vous n’avez presque jamais besoin d’utiliser eof en Perl parce que les opérateurs d’entrée retournent la valeur
undef quand ils n’ont plus d’informations à lire ou s’il y a eu une erreur.
eval EXPR
eval BLOC
Dans sa première forme, la valeur retournée par EXPR est parcourue puis exécutée comme un petit programme Perl. La
valeur de l’expression (qui est elle-même déterminée dans un contexte scalaire) est d’abord parcourue puis, s’il n’y a pas eu
d’erreurs, exécutée dans le contexte du programme courant, de telle sorte que toute assignation de variable, et toute dé?nition
de subroutine ou de format perdure après cette exécution. Notez que la valeur est parcourue à chaque exécution d’évaluation. Si
EXPR est omis, évalue $_. Cette forme est typiquement utilisée pour repousser la compilation et l’exécution du texte contenu
dans EXPR jusqu’à l’exécution du programme.
Dans sa seconde forme, le code à l’intérieur du BLOC est parcouru une seule fois – au même moment que la compilation du
code entourant l’évaluation – et exécuté dans le contexte du programme Perl courant. Cette forme est typiquement utilisée
pour intercepter des exceptions plus ef?cacement que la première (voir ci-dessous), en fournissant aussi le béné?ce d’une
véri?cation du code dans le BLOC lors de la compilation.
Le point-virgule ?nal, le cas échéant, peut être omis dans EXPR ou à l’intérieur du BLOC.
Dans les deux formes, la valeur retournée est la valeur de la dernière expression évaluée à l’intérieur du mini-programme ; il est
aussi aussi possible d’utiliser un retour explicite (via return), exactement comme pour les routines. L’expression fournissant
la valeur de retour est évaluée en contexte vide, scalaire ou de liste, en fonction du contexte de l’évaluation elle-même. Voir
le titre wantarray dans ce document pour de plus amples informations sur la façon dont le contexte d’évaluation peut être
déterminé.
En cas d’erreur de syntaxe ou d’exécution ou si une instruction die() est exécutée, une valeur indé?nie (undef) est retournée
par eval() et le message d’erreur est assigné à $@. S’il n’y a pas d’erreur, vous avez la garantie que la valeur de $@ sera
une chaîne de caractères vide. Prenez garde au fait qu’utiliser eval() ne dispense Perl ni d’af?cher des messages d’alerte
(warnings) sur STDERR ni d’assigner ses messages d’alerte dans $@. Pour ce faire, il vous faut utiliser les capacités de
$SIG{__WARN__}. Voir le titre warn dans ce document et le manuel perlvar.
Étant donné que eval() intercepte les erreurs non fatales, c’est très pratique pour déterminer si une fonctionnalité (telle que
socket() ou symlink()) est supportée. C’est aussi le mécanisme d’interception d’exception de Perl lorsque l’opérateur die
est utilisé pour les soulever.
Si le code à exécuter ne varie pas, vous devriez utiliser la seconde forme avec un BLOC pour intercepter les erreurs d’exécution
sans supporter l’inconvénient de le recompiler à chaque fois. L’erreur, le cas échéant, est toujours retournée dans $@. Exemples:
# rend une division par zéro non fatale
eval { $answer = $a / $b; }; warn $@ if $@;
# même chose, mais moins efficace
eval ’$answer = $a / $b’; warn $@ if $@;
# une erreur de compilation
eval { $answer = };
# MAUVAIS
# une erreur d’exécution
eval ’$answer =’;
# sets $@
En utilisant la forme eval{} pour une interception d’exception dans des bibliothèques, vous pourriez souhaiter ne pas exécuter
une éventuelle subroutine attachée à __DIE__ par le code de l’utilisateur. Dans ce cas, vous pouvez utiliser la construction
local $SIG{__DIE__} comme dans l’exemple ci-dessous :
# une interception d’exception de division par zéro très privée
eval { local $SIG{’__DIE__’}; $answer = $a / $b; };
warn $@ if $@;
Ceci est spécialement signi?catif, étant donné que les subroutine attachée à __DIE__ peuvent appeler die() à nouveau, ce qui
a pour effet de changer leurs messages d’erreur :
# les subroutines attachées à __DIE__
# peuvent modifier les messages d’erreur
{
local $SIG{’__DIE__’} =
sub { (my $x = $_[0]) =~ s/foo/bar/g; die $x };
eval { die "foo lives here" };
print $@ if $@;
# affiche "bar lives here"
}
84

7.1. DESCRIPTION
perlfunc
Étant donné que cela favorise une action à distance, ce comportement contre-intuitif pourrait changer dans une version future.
Avec eval(), vous devriez faire particulièrement attention à ce qui est examiné, et quand :
eval $x;
# CAS 1
eval "$x";
# CAS 2
eval ’$x’;
# CAS 3
eval { $x };
# CAS 4
eval "\$$x++";
# CAS 5
$$x++;
# CAS 6
Les cas 1 et 2 ci-dessus se comportent de la même façon : ils exécutent le code inclus dans la variable $x. (Bien que le cas 2
ait des guillemets qui font se demander au lecteur ce qui se passe – réponse : rien.) Les cas 3 et 4 se comportent aussi de la
même façon : ils exécutent le code ’$x’ qui ne fait rien que retourner la valeur de $x. (Le cas 4 est préférable pour des raisons
purement visuelles mais aussi parce qu’il a l’avantage d’être compilé lors de la compilation plutôt que lors de l’exécution.) Le
cas 5 est un endroit où vous DEVRIEZ normalement souhaiter utiliser des guillemets, sauf que dans ce cas particulier, vous
pouvez juste utiliser les références symboliques à la place, comme dans le cas 6.
Un eval BLOC n’est pas considéré comme une boucle. Par conséquent, les instructions de contrôle de boucles next, last, ou
redo ne peuvent être utilisées pour quitter ou refaire le bloc.
exec LISTE
exec PROGRAMME LISTE
La fonction exec() exécute une commande système et ne retourne jamais – utilisez system() à la place de exec() si
vous souhaitez qu’elle retourne. Elle échoue et retourne FAUX si et seulement si la commande n’existe pas et est exécutée
directement plutôt que par votre interpréteur de commandes (shell) (cf. ci-dessous).
Comme c’est une erreur courante d’utiliser exec() au lieu de system(), Perl vous alerte si l’expression suivante n’est pas
die(), warn(), ou exit() (si -w est utilisé – ce que vous faites toujours, évidemment.) Si vous voulez vraiment faire suivre
le exec() d’une autre expression, vous pouvez utiliser l’une de ces méthodes pour éviter l’avertissement :
exec (’foo’)
or print STDERR "couldn’t exec foo: $!";
{ exec (’foo’) }; print STDERR "couldn’t exec foo: $!";
S’il y a plus d’un argument dans la LISTE, ou si la LISTE est un tableau de plus d’une valeur, appelle execvp(3) avec
les arguments de la LISTE. S’il n’y a qu’un seul argument scalaire ou un tableau à un seul élément et que cet argument
contient des méta-caractères du shell, l’argument entier est passé à l’interpréteur de commandes shell pour son expansion et
son exécution (il s’agit de /bin/sh -c sur les plates-formes Unix, mais cela varie en fonction des plates-formes.) S’il n’y a
aucun méta-caractères du shell dans l’argument, il est découpé en mots et passé directement à execvp() qui est plus ef?cace.
Exemples :
exec ’/bin/echo’, ’Your arguments are: ’, @ARGV;
exec "sort $outfile | uniq";
Si vous ne souhaitez pas vraiment exécuter le premier argument mais plutôt l’utiliser pour dissimuler le nom du programme
réellement utilisé, vous pouvez spéci?er le vrai programme à exécuter comme un "objet indirect" (sans virgule) au début de
la LISTE. (Ceci force toujours l’interprétation de la LISTE comme une liste multivaluée, même s’il n’y a qu’un seul scalaire
dedans.) Exemple :
$shell = ’/bin/csh’;
exec $shell ’-sh’;
# prétend qu’il s’agit d’un login shell
ou, plus directement,
exec {’/bin/csh’} ’-sh’;
# prétend qu’il s’agit d’un login shell
Quand les arguments sont exécutés par le shell système, les résultats seront dépendants de ses caprices et de ses capacités. Voir
le titre ‘CHAINE‘ dans le manuel perlop pour plus de détails.
Utiliser un objet indirect avec exec() ou system() est aussi plus sûr. Cet usage force l’interprétation des arguments comme
une liste multivaluée, même si elle ne contient qu’un seul élément. De cette façon, vous ne risquez rien des jokers du shell ou
de la séparation des mots par des espaces.
@args = ( "echo surprise" );
system @args;
# sujet à des échappement du shell
# si @args == 1
system { $args[0] } @args;
# sûr même avec une liste à un seul élément
85

7.1. DESCRIPTION
perlfunc
La première version, celle sans l’objet indirect, exécute le programme echo, en lui passant "surprise" comme argument. La
seconde version ne le fait pas – elle essaie d’exécuter un programme littéralement appelé "echo surprise", ne le trouve pas et
assigne à $? une valeur non nulle indiquant une erreur.
Depuis la version v5.6.0, Perl essaie avant d’effectuer le exec()de vider tous les tampons des ?chiers ouverts en écriture mais ce
n’est pas le cas sur toutes les plates-formes (voir le manuel perlport). Pour être plus sûr, vous devriez positionné la variable $|
($AUTOFLUSH en anglais) ou appelé la méthode autoflush() des objets IO::Handle pour chacun des descripteurs ouverts
a?n d’éviter toute perte de données.
Remarquez que exec() n’exécutera ni vos blocs END ni les méthodes DESTROY de vos objets.
exists EXPR
Si EXPR spéci?e un élément d’une table de hachage ou d’un tableau, retourne VRAI si cet élément existe, même si la valeur
correspondante est indé?nie. L’élément n’est pas créé automagiquement si il n’existe pas.
print "Exists\n"
if exists $array{$key};
print "Defined\n"
if defined $array{$key};
print "True\n"
if $array{$key};
print "Exists\n"
if exists $hash{$key};
print "Defined\n"
if defined $hash{$key};
print "True\n"
if $hash{$key};
print "Exists\n"
if exists $array[$index];
print "Defined\n"
if defined $array[$index];
print "True\n"
if $array[$index];
Un élément d’une table de hachage ou d’un tableau ne peut être VRAI que s’il est dé?ni, et dé?ni que s’il existe, mais la
réciproque n’est pas nécessairement vraie.
Si EXPR spéci?e le nom d’une subroutine, retourne VRAI si la subroutine spéci?ée a déjà été déclarée, même si elle est
toujours indé?nie. Utiliser un nom de subroutine pour tester si elle existe (exists) ou si elle est dé?nie (de?ned) ne compte pas
comme une déclaration.
print "Exists\n"
if exists &subroutine;
print "Defined\n"
if defined &subroutine;
Notez que l’expression EXPR peut être arbitrairement compliquée tant qu’au ?nal, elle désigne une subroutine ou un élément
d’une table de hachage ou d’un tableau :
if (exists $ref->{A}->{B}->{$key})
{ }
if (exists $hash{A}{B}{$key})
{ }
if (exists $ref->{A}->{B}->[$ix])
{ }
if (exists $hash{A}{B}[$ix])
{ }
if (exists &{$ref->{A}{B}{$key}})
{ }
Bien que l’élément le plus profond ne soit pas soudainement créer juste parce son existence a été testée, les éléments inter-
médiaires, eux, le seront. Par conséquent, $ref->{"A"} et $ref->{"A"}->{"B"} seront créés à cause du test d’existence de
l’élément lié à la clé $key ci-dessus. Cela arrivera à chaque fois que l’opérateur ?èche est utilisé, y compris dans le cas suivant :
undef $ref;
if (exists $ref->{"Some key"})
{ }
print $ref;
# affiche HASH(0x80d3d5c)
Cette génération spontanée un peu surprenante qui, au premier coup d’oeil (ni même au second d’ailleurs), n’est pas dans le
contexte d’une lvalue pourrait être supprimée dans une version future.
Voir le titre Pseudo-tables de hachage : utiliser un tableau comme table de hachage dans le manuel perlref pour des informa-
tions spéci?ques concernant l’utilisation de exists() sur les pseudo-hachages.
L’utilisation d’un appel à une subroutine à la place du nom de cette subroutine comme argument de exists() est une erreur.
exists &sub;
# OK
exists &sub();
# Erreur
exit EXPR
Évalue EXPR puis quitte immédiatement avec cette valeur. Exemple :
$ans = <STDIN>;
exit 0 if $ans =~ /^[Xx]/;
86

7.1. DESCRIPTION
perlfunc
Voir aussi die(). Si l’expression EXPR est omise, quitte avec le statut 0. Les seules valeurs universellement reconnues pour
EXPR sont 0 en cas de réussite et 1 en cas d’erreur ; toutes les autres valeurs sont sujettes à des interprétations imprévisibles, en
fonction de l’environnement dans lequel le programme Perl est exécuté. Par exemple, terminer un ?ltre de messages entrants
de sendmail avec comme valeur 69 (EX_UNAVAILABLE) provoquera la non livraison du message, mais ce n’est pas vrai
partout.
Vous ne devriez pas utiliser exit() pour interrompre une routine s’il existe une chance pour que quelqu’un souhaite intercepter
une erreur qui arrive. Utilisez die() à la place, qui peut être intercepté par un eval().
La fonction exit() ne termine pas toujours le process immédiatement. Elle appelle d’abord toutes les routines END dé?nies, mais
ces routines END ne peuvent pas annuler la terminaison. De la même façon, tout destructeur d’objet qui doit être appelé le sera
avant la sortie. Si cela pose problème, vous pouvez appelé POSIX:_exit($status) pour éviter le traitement des destructeurs
et des subroutine END. Voir le manuel perlmod pour les détails.
exp EXPR
exp
Retourne (la base des logarithmes naturels ou népérien) élevé à la puissance EXPR. Si EXPR est omis, retourne exp($_).
fcntl DESCRIPTEUR, FONCTION, SCALAIRE
Implémente la fonction fcntl(2). Vous devrez probablement d’abord écrire
use Fcntl;
pour avoir les dé?nitions de constantes correctes. Le traitement de l’argument et la valeur de retour se fait exactement de la
même manière que ioctl() plus bas. Par exemple :
use Fcntl;
fcntl($filehandle, F_GETFL, $packed_return_buffer)
or die "can’t fcntl F_GETFL: $!";
Vous n’avez pas à véri?er le résultat de fnctl() via defined(). Comme ioctl(), elle transforme le retour 0 de l’appel
système en un "0 but true" en Perl. Cette chaîne est vraie dans un contexte booléen et vaut 0 dans un contexte numérique.
Elle est aussi exempte des alertes habituelles de -w sur les conversions numériques impropres.
Notez que fcntl() produira une erreur fatale si elle est utilisée sur une machine n’implémentant pas fcntl(2). Voir le module
Fcntl ou fcntl(2) pour connaître les fonctions disponibles sur votre système.
?leno DESCRIPTEUR
Retourne le numéro système associé à un descripteur de ?chier. Ceci est utile pour construire des vecteurs pour select() et
pour les opérations POSIX de manipulation bas niveau de terminaux tty. Si DESCRIPTEUR est une expression, la valeur est
prise comme un descripteur indirect, généralement son nom.
Vous pouvez utiliser ceci pour déterminer si deux descripteurs se réfèrent au même numéro sous-jacent :
if (fileno(THIS) == fileno(THAT)) {
print "THIS and THAT are dups\n";
}
?ock DESCRIPTEUR,OPERATION
Appelle ?ock(2), ou son émulation, sur le DESCRIPTEUR. Retourne VRAI en cas de succès, FAUX en cas d’échec. Pro-
duit une erreur fatale lorsqu’il est utilisé sur une machine n’implémentant pas ?ock(2), le verrouillage fcntl(2), ou lockf(3).
flock() est une interface Perl portable de verrouillage de ?chiers, bien qu’il ne verrouille que des ?chiers en entier, et non
pas des enregistrements.
La sémantique non évidente mais néanmoins traditionnelle de flock consiste à attendre indé?niment jusqu’à la libération
du verrou. Ce verrou est purement consultatif. De tels verrous sont plus faciles d’utilisation mais offrent moins de garantie.
Cela signi?e que des ?chiers verrouillés via flock peuvent être modi?és par des programmes n’utilisant pas flock. Voir le
manuel perlport ou les pages de manuel de votre système pour la documentation plus détaillée. Il vaut mieux faire avec ce
comportement traditionnel si vous visez la portabilité. (Sinon, libre à vous d’utiliser les fonctionnalités ("features") de votre
système d’exploitation. Les contraintes de portabilité ne doivent pas vous empêcher de faire ce que voulez.)
OPERATION peut être LOCK_SH, LOCK_EX ou LOCK_UN, éventuellement combinée avec LOCK_NB. Ces constantes
ont traditionnellement pour valeurs 1, 2, 8 et 4, mais vous pouvez utiliser les noms symboliques s’ils sont importés du module
Fcntl, soit individuellement, soit en tant que groupe en utilisant la balise ’:?ock’. LOCK_SH demande un verrou partagé,
LOCK_EX demande un verrou exclusif et LOCK_UN libère un verrou précédemment demandé. Si LOCK_NB est ajouté à
LOCK_SH ou LOCK_EX (via un ’ou’ bit à bit) alors flock() retournera immédiatement plutôt que d’attendre la libération
du verrou (véri?ez le code de retour pour savoir si vous l’avez obtenu).
Pour éviter une mauvaise synchronisation, Perl vide le tampon du DESCRIPTEUR avant de le (dé)verrouiller.
87

7.1. DESCRIPTION
perlfunc
Notez que l’émulation construite avec lockf(3) ne fournit pas de verrous partagés et qu’il exige que DESCRIPTEUR soit
ouvert en écriture. Ce sont les sémantiques qu’implémente lockf(3). La plupart des systèmes (si ce n’est tous) implémentent
toutefois lockf(3) en termes de verrous fcntl(2), la différence de sémantiques ne devrait dont pas gêner trop de monde.
Notez aussi que certaines versions de flock() ne peuvent pas verrouiller des choses à travers le réseau, vous devriez utilisez
des appels à fcntl() plus spéci?ques au système dans ce but. Si vous le souhaitez, vous pouvez contraindre Perl à ignorer la
fonction ?ock(2) de votre système et lui fournir ainsi sa propre émulation basée sur fcntl(2), en passant le ?ag -Ud_flock au
programme Con?gure lors de la con?guration de perl.
Voici un empilage de mails pour les systèmes BSD.
use Fcntl ’:flock’; # import des constantes LOCK_*
sub lock {
flock(MBOX,LOCK_EX);
# et, si quelqu’un ajoute
# pendant notre attente
seek(MBOX, 0, 2);
}
sub unlock {
flock(MBOX,LOCK_UN);
}
open(MBOX, ">>/usr/spool/mail/$ENV{’USER’}")
or die "Can’t open mailbox: $!";
lock();
print MBOX $msg,"\n\n";
unlock();
Su les systèmes qui possèdent un vrai ?ock(), les verrous sont hérités à travers les appels à fork() alors que ceux qui s’appuient
sur la fonction fcntl() plus capricieuse perdent les verrous, rendant ainsi l’écriture de serveur plus dif?cile.
Voir aussi le titre DB_File dans ce document pour d’autres exemples avec ?ock().
fork
Effectue un appel système fork(2) pour créer un nouveau processus exécutant le même programme au même point. Retourne
l’identi?ant (pid) de l’enfant au processus père, 0 au processus ?ls ou undef en cas d’échec. Les descripteurs de ?chiers (et
parfois les verrous posés sur ces descripteurs) sont partagés sinon tout le reste est recopié. Sur la plupart des systèmes qui
supportent l’appel système fork(), une grande attention a été portée pour qu’il soit extrêmement ef?cient (par exemple en
utilisant la méthode de copie-à-l-écriture sur les pages mémoires contenant des données). C’est donc la paradigme dominant
pour la gestion du multi-tâches durant les dernières décennies.
Depuis la version v5.6.0, Perl tente de vider les tampons de tous les ?chiers ouverts en écriture avant d’effectuer le fork() mais
cela n’est pas supporté sur toutes les plates-formes (voir le manuel perlport). Pour être plus sûr, vous devriez positionné la va-
riable $| ($AUTOFLUSH en anglais) ou appelé la méthode autoflush() des objets IO::Handle pour chacun des descripteurs
ouverts a?n d’éviter toute duplication de données.
Si vous dupliquez avec fork() sans attendre votre ?ls, vous allez accumuler des zombis. Sur certains systèmes, vous pouvez
éviter cela en positionnant $SIG{CHLD} à "IGNORE". Voir aussi le manuel perlipc pour des exemples d’utilisation de fork() et
de suppression d’enfants moribonds.
Notez que si votre ?ls dupliqué hérite de descripteurs de ?chier systèmes, tels que STDIN et STDOUT, qui sont en fait
connectés par un tube ou une socket, même si vous sortez du programme, alors le serveur distant (disons tels que httpd ou rsh)
ne saura pas que vous avez terminé. Vous devriez les réouvrir vers /dev/null en cas de problème.
format
Déclare un format visuel utilisable par la fonction write(). Par exemple :
format Something =
Test: @<<<<<<<< @||||| @>>>>>
$str,
$%,
’$’ . int($num)
.
$str = "widget";
$num = $cost/$quantity;
$~ = ’Something’;
write;
88

7.1. DESCRIPTION
perlfunc
Voir le manuel perlform pour de nombreux détails et exemples.
formline IMAGE,LISTE
C’est une fonction interne utilisée par les formats (format), bien que vous puissiez aussi l’appeler. Elle formate (voir le manuel
perlform) une liste de valeurs selon le contenu de IMAGE, plaçant la sortie dans l’accumulateur du format de sortie $ˆA (ou
$ACCUMULATOR en anglais). Finalement, lorsqu’un write() est effectué, le contenu de $ˆA est écrit dans un descripteur de
?chier, mais vous pouvez aussi lire $ˆA vous-même et réassigner "" à $ˆA. Notez qu’un format typique appelle formline une
fois par ligne du formulaire mais la fonction formline elle-même ne se préoccupe pas du nombre de passage à la ligne inclus
dans l’IMAGE. Ceci signi?e que ˜ et ˜˜ traiteront l’IMAGE complète comme une seule ligne. Vous pouvez donc utiliser de
multiples formline pour implémenter un seul format d’enregistrement, tout comme le compilateur de format.
Faites attention si vous utilisez des guillemets autour de l’image, car un caractère "@" pourrait être pris pour le début d’un nom
de tableau. formline() retourne toujours VRAI. Cf. le manuel perlform pour d’autres exemples.
getc DESCRIPTEUR
getc
Retourne le prochain caractère du ?chier d’entrée attaché au DESCRIPTEUR ou la valeur indé?nie (undef) à la ?n du ?chier
ou en cas d’échec. Si le DESCRIPTEUR est omis, utilise STDIN. Ce n’est pas particulièrement ef?cace. De plus, ce n’est pas
utilisable tel quel pour obtenir des caractères sans que l’utilisateur presse ENTER. Pour ça, essayez quelque chose comme :
if ($BSD_STYLE) {
system "stty cbreak </dev/tty >/dev/tty 2>&1";
}
else {
system "stty", ’-icanon’, ’eol’, "\001";
}
$key = getc(STDIN);
if ($BSD_STYLE) {
system "stty -cbreak </dev/tty >/dev/tty 2>&1";
}
else {
system "stty", ’icanon’, ’eol’, ’^@’; # ASCII null
}
print "\n";
Déterminer la valeur de $BSD_STYLE est laissé en exercice au lecteur.
La fonction POSIX::getattr() peut faire ceci de façon plus portable sur des systèmes compatibles POSIX. Voir aussi le
module Term::ReadKey de votre site CPAN le plus proche. Les détails sur CPAN peuvent être trouvés dans le titre CPAN
dans le manuel perlmod.
getlogin
Implémente la fonction de la bibliothèque C portant le même nom et qui, sur la plupart des systèmes, retourne le login courant
à partir de /etc/utmp, si il existe. Si l’appel retourne null, utilisez getpwuid().
$login = getlogin || getpwuid($<) || "Kilroy";
N’utilisez pas getlogin() pour de l’authenti?cation : ce n’est pas aussi sûr que getpwuid().
getpeername SOCKET
Renvoie l’adresse sockaddr compactée (voir pack()) de l’autre extrémité de la connexion SOCKET.
use Socket;
$hersockaddr
= getpeername(SOCK);
($port, $iaddr) = unpack_sockaddr_in($hersockaddr);
$herhostname
= gethostbyaddr($iaddr, AF_INET);
$herstraddr
= inet_ntoa($iaddr);
getpgrp PID
Renvoie le groupe courant du processus dont on fournit le PID. Utilisez le PID 0 pour obtenir le groupe courant du processus
courant. Cela engendra une exception si on l’utilise sur une machine qui n’implémente pas getpgrp(2). Si PID est omis,
renvoie le groupe du processus courant. Remarquez que la version POSIX de getpgrp() ne prend pas d’argument PID donc
seul PID==0 est réellement portable.
getppid
Renvoie l’id du processus parent.
89

7.1. DESCRIPTION
perlfunc
getpriority WHICH,WHO
Renvoie la priorité courant d’un processus, d’un groupe ou d’un utilisateur. (Voir le manuel getpriority(2).) Cela engendra une
exception si on l’utilise sur une machine qui n’implémente pas getpriority(2).
getpwnam NAME
getgrnam NAME
gethostbyname NAME
getnetbyname NAME
getprotobyname NAME
getpwuid UID
getgrgid GID
getservbyname NAME,PROTO
gethostbyaddr ADDR,ADDRTYPE
getnetbyaddr ADDR,ADDRTYPE
getprotobynumber NUMBER
getservbyport PORT,PROTO
getpwent
getgrent
gethostent
getnetent
getprotoent
getservent
setpwent
setgrent
sethostent STAYOPEN
setnetent STAYOPEN
setprotoent STAYOPEN
setservent STAYOPEN
endpwent
endgrent
endhostent
endnetent
endprotoent
endservent
Ces routines réalisent exactement les mêmes fonctions que leurs homologues de la bibliothèque système. Dans un contexte de
liste, les valeurs retournées par les différentes routines sont les suivantes :
($name,$passwd,$uid,$gid,
$quota,$comment,$gcos,$dir,$shell,$expire) = getpw*
($name,$passwd,$gid,$members) = getgr*
($name,$aliases,$addrtype,$length,@addrs) = gethost*
($name,$aliases,$addrtype,$net) = getnet*
($name,$aliases,$proto) = getproto*
($name,$aliases,$port,$proto) = getserv*
(Si une entrée n’existe pas, vous récupérerez une liste vide.)
La signi?cation exacte du champ $gcos varie mais contient habituellement le nom réel de l’utilisateur (au contraire du nom de
login) et d’autres informations pertinentes pour cet utilisateur. Par contre, sachez que sur de nombreux systèmes, les utilisateurs
peuvent changer eux-mêmes ces informations. Ce n’est donc pas une information de con?ance. Par conséquent $gcos est
souillée (voir le manuel perlsec). Les champs $passwd, $shell ainsi que l’interpréteur de commandes (login shell) et le mot de
passe crypté sont aussi souillés pour les mêmes raisons.
Dans un contexte scalaire, vous obtenez le nom sauf lorsque la fonction fait une recherche par nom auquel cas vous récupérerez
autre chose. (Si une entrée n’existe pas vous récupérerez la valeur undef.) Par exemple :
90

7.1. DESCRIPTION
perlfunc
$uid
= getpwnam($name);
$name
= getpwuid($num);
$name
= getpwent();
$gid
= getgrnam($name);
$name
= getgrgid($num;
$name
= getgrent();
#etc.
Dans getpw*(), les champs $quota, $comment et $expire sont des cas spéciaux dans le sens où ils ne sont pas supportés sur
de nombreux systèmes. Si $quota n’est pas supporté, c’est un scalaire vide. Si il est supporté, c’est habituellement le quota
disque. Si le champ $comment n’est pas supporté, c’est un scalaire vide. Si il est supporté, c’est habituellement le commentaire
« administratif » associé à l’utilisateur. Sur certains systèmes, le champ $quota peut être $change ou $age, des champs qui
sont en rapport avec le vieillissement du mot de passe. Sur certains systèmes, le champ $comment peut être $class. Le champ
$expire, s’il est présent, exprime la période d’expiration du compte ou du mot de passe. Pour connaître la disponibilité et le
sens exacte de tous ces champs sur votre système, consultez votre documentation de getpwnam(3) et le ?chier pwd.h. À partir
de Perl, vous pouvez trouver le sens de vos champs $quota et $comment et savoir si vous avez le champ $expire en utilisant
le module Config pour lire les valeurs de d_pwquota, d_pwage, d_pwchange, d_pwcomment et d_pwexpire. Les ?chiers de
mots de passe cachés (shadow password) ne sont supportés que si l’implémentation de votre système est faite telle que les
appels aux fonctions normales de la bibliothèque C accèdent à ces ?chiers lorsque vos privilèges vous y autorisent. Tout autre
implémentation incorrecte via des appels à une bibliothèque séparée ne sont pas supportés.
La valeur $members renvoyée par les fonctions getgr*() est la liste des noms de login des membres du groupe séparés par des
espaces.
Pour les fonctions gethost*(), si la variable h_errno est supportée en C, sa valeur sera retournée via $? si l’appel à la fonction
échoue. La valeur de @addrs qui est retournée en cas de succès est une liste d’adresses à plat telle que retournée par l’appel
système correspondant. Dans le domaine Internet, chaque adresse fait quatre octets de long et vous pouvez la décompacter en
disant quelque chose comme :
($a,$b,$c,$d) = unpack(’C4’,$addr[0]);
Si vous êtes fatigué de devoir vous souvenir que tel élément de la liste retournée correspond à telle valeur, des inter-
faces par nom sont fournies par les modules File::stat, Net::hostent, Net::netent, Net::protoent, Net::servent,
Time::gmtime, Time::localtime et User::grent. Ils remplacent les appels internes normaux par des versions qui renvoient
des objets ayant le nom approprié pour chaque champ. Par exemple :
use File::stat;
use User::pwent;
$is_his = (stat($filename)->uid == pwent($whoever)->uid);
Bien que les deux appels se ressemblent (appel à la méthode ’uid’), ce n’est pas la même chose car l’objet File::stat est
différent de l’objet User::pwent.
getsockname SOCKET
Renvoie l’adresse sockaddr compactée de cette extrémité de la connexion SOCKET si vous ne connaissez pas cette adresse
car vous avez différentes adresses IP utilisables pour établir cette connexion.
use Socket;
$mysockaddr = getsockname(SOCK);
($port, $myaddr) = sockaddr_in($mysockaddr);
printf "Connect to %s [%s]\n",
scalar gethostbyaddr($myaddr, AF_INET),
inet_ntoa($myaddr);
getsockopt SOCKET,LEVEL,OPTNAME
Renvoie l’option demandée de SOCKET ou undef en cas d’erreur.
glob EXPR
glob
Retourne la valeur de EXPR en tenant compte de l’expansion des noms de ?chiers telle que le shell standard Unix /bin/sh la
ferait. C’est la fonction interne qui implémente l’opérateur <*.c> mais vous pouvez l’utiliser directement. Si EXPR est omis,
$_ est utilisé à la place. L’opérateur <*.c> est présenté plus en détail dans le titre Les opérateurs d’E/S dans le manuel perlop.
Depuis la version v5.6.0, cet opérateur est implémenté via l’extension standard File::Glob. Voir le manuel File::Glob pour
plus de détails.
91

7.1. DESCRIPTION
perlfunc
gmtime EXPR
Convertit une date telle que celle retournée par la fonction time en un tableau de 9 éléments avec la date liée au fuseau horaire
du méridien de Greenwich standard. On l’utilise typiquement de la manière suivante :
#
0
1
2
3
4
5
6
7
8
($sec,$min,$heure,$mjour,$mois,$annee,$sjour,$ajour,$isdst) =
gmtime(time);
Tous les éléments du tableau sont numériques et restent tels qu’ils apparaissent dans la structure ’struct tm’. $sec, $min et
$heure sont les secondes, les minutes et l’heure de l’instant spéci?é. $mjour est le quantième du mois et $mois est le mois
lui-même, dans l’intervalle 0..11 avec 0 pour janvier et 11 pour décembre. $annee est le nombre d’années depuis 1900 et
donc $annee vaut 123 en l’an 2023. $sjour est le jour de la semaine avec 0 pour le dimanche et 3 pour le mercredi. $ajour
est le jour de l’année dans l’intervalle 1..365 (ou 1..366 pour les années bissextiles.) $isdst est vrai si l’heure d’été est en
cours à la date spéci?ée et faux sinon.
Remarquez bien que $annee n’est pas que les deux derniers chiffres de l’année. Si vous supposez cela, vous créez des pro-
grammes non compatible an 2000 – et vous ne voulez pas faire cela, n’est-ce pas ?
La bonne méthode pour obtenir une année complète sur 4 chiffres est tout simplement :
$annee += 1900;
Et pour obtenir les deux derniers chiffres de l’année (e.g. ’01’ en 2001):
$annee = sprintf("%02d", $annee % 100);
Si EXPR est omis, calcule gmtime(time).
Dans un contexte scalaire, retourne la valeur de ctime(3) :
$now_string = gmtime;
# e.g., "Thu Oct 13 04:54:34 1994"
Voir aussi la fonction timegm() fournit par le module Time::Local et la fonction strftime(3) disponible via le module POSIX.
La valeur scalaire n’est pas dépendante du locale, voir le manuel perllocale, mais est construite en interne par Perl. Voir aussi
le module Time::Local et les fonctions strftime(3) et mktime(3) du module POSIX. Pour obtenir quelque chose de similaire
mais dont les chaînes de caractères des dates dépendent du locale, paramétrez vos variables d’environnement liées au locale
(voir le manuel perllocale) et essayez par exemple :
use POSIX qw(strftime);
$now_string = strftime "%a %b %e %H:%M:%S %Y", gmtime;
Notez que les séquences %a et %b qui sont les formes courtes du jour de la semaine et du mois de l’année, n’ont pas obligatoi-
rement 3 caractères de long dans tous les locale.
goto LABEL
goto EXPR
goto &NAME
La forme goto-LABEL trouve la ligne étiquetée par LABEL et continue l’exécution à cette ligne. On en peut pas l’utiliser
pour sauter à l’intérieur d’une construction qui nécessite une initialisation telle qu’une subroutine ou une boucle foreach.
On ne peut pas non plus l’utiliser pour aller dans une construction qui peut être optimisée ou pour sortir d’un bloc ou d’une
subroutine donné à sort(). On peut par contre l’utiliser pour aller n’importe où dans la portée actuelle même pour sortir des
subroutines bien qu’il soit meilleur d’utiliser pour cela d’autres constructions telles que last ou die(). L’auteur de Perl n’a
jamais ressenti le besoin d’utiliser cette forme de goto (en Perl bien sûr – en C, c’est une autre histoire).
La forme goto-EXPR attend un nom d’étiquette dont la portée sera résolue dynamiquement. Cela autorise les goto calculés à
la FORTRAN mais ce n’est pas vraiment recommandé si vous vous souciez de la maintenance.
goto ("FOO", "BAR", "GLARCH")[$i];
La forme goto-&NAME est vraiment différente des autres formes de goto. En fait, ce n’est pas du tout un goto et il n’a donc pas
les stigmates habituellement associés aux autres goto. Cette forme substitue l’appel de la subroutine en cours d’exécution par
un appel à la subroutine donnée en argument. C’est utilisé par les routines AUTOLOAD qui désirent charger une autre subroutine
puis tout faire comme si c’était cette autre subroutine qui avait réellement été appelée (sauf que toutes les modi?cations faites
à @_ dans la subroutine courante sont propagées à l’autre subroutine). Après le goto, pas même caller() n’est capable de
s’apercevoir que la subroutine initiale a été appelée au préalable.
NAME n’est pas nécessairement le nom d’une subroutine ; cela peut être un variable scalaire contenant une référence à du
code ou un bloc dont l’évaluation produit une référence à du code.
grep BLOC LISTE
92

7.1. DESCRIPTION
perlfunc
grep EXPR,LISTE
Cette fonction est similaire dans l’esprit mais pas identique à grep(1) et tous ses dérivés. En particulier, elle n’est pas limitée
à l’utilisation d’expressions rationnelles.
Elle évalue le bloc BLOC ou l’expression EXPR pour chaque élément de LISTE (qui est localement lié à $_) et retourne la liste
des valeurs constituée des éléments pour lesquels l’expression est évaluée à true (vrai). Dans un contexte scalaire, retourne le
nombre de fois où l’expression est vraie (true).
@foo = grep(!/^#/, @bar);
# supprime les commentaires
ou de manière équivalente :
@foo = grep {!/^#/} @bar;
# supprime les commentaires
Remarquez que, puisque $_ est un référence dans la liste de valeurs, il peut être utilisé pour modi?er les éléments du tableau.
Bien que ce soit supporté et parfois pratique, cela peut aboutir à des résultats bizarres si LISTE n’est pas un tableau nommé.
De manière similaire, grep renvoie des alias de la liste originale exactement comme le fait une variable de boucle for. Et donc,
modi?er un élément d’une liste retournée par grep (par exemple dans un foreach, un map() ou un autre grep()) modi?e
réellement l’élément de la liste originale.
Voir aussi le titre map dans ce document pour obtenir un tableau composé des résultats de BLOC ou EXPR.
hex EXPR
hex
Interprète EXPR comme une chaîne hexadécimale et retourne la valeur correspondante. (Pour convertir des chaînes qui com-
mencent soit par 0 soit par 0x voir le titre oct dans ce document.) Si EXPR est omis, c’est $_ qui est utilisé.
print hex ’0xAf’; # affiche ’175’
print hex ’aF’;
# idem
import
Il n’existe pas de fonction interne import(). C’est juste une méthode ordinaire (une subroutine) dé?nie (ou héritée) par les
modules qui veulent exporter des noms vers d’autres modules. Le fonction use() appelle la méthode import() du paquetage
utilisé. Voir aussi le titre use() dans ce document, le manuel perlmod et le manuel Exporter.
index CHAINE,SUBSTR,POSITION
index CHAINE,SUBSTR
La fonction index() recherche une chaîne dans une autre mais sans les fonctionnalités génériques de reconnaissance de motifs
des expressions rationnelles. Retourne la position de la première occurrence du SUBSTR dans CHAINE à partir de POSITION
inclus. Si POSITION est omis, le recherche commence au début de la chaîne. La valeur retournée est relative à 0 (ou à la valeur
que vous avez affectée à la variable $[ – mais ce n’est pas à faire). Si la sous-chaîne SUBSTR n’est pas trouvée, la valeur
retournée est la valeur de référence moins 1 (habituellement -1).
int EXPR
int
Retourne la partie entière de EXPR. Si EXPR est omis, c’est $_ qui est utilisé. Vous ne devriez pas utiliser cette fonction pour
faire des arrondis parce qu’elle tronque la valeur vers 0 et parce que la représentation interne des nombre en virgule ?ottante
produit parfois des résultats contre-intuitifs. Par exemple int(-6.725/0.025) produit -268 au lieu de -269 ; C’est dû aux
erreurs de calcul qui donne un résultat comme -268.99999999999994315658. Habituellement sprintf() et printf() ou les
fonctions POSIX::floor et POSIX::ceil vous seront plus utiles que int().
ioctl DESCRIPTEUR,FONCTION,SCALAIRE
Implémente la fonction ioctl(2). Vous aurez probablement à dire :
require ""; # probablement dans 
en premier lieu pour obtenir les dé?nitions correctes des fonctions. Si  n’existe pas ou ne donne pas les dé?nitions
correctes, vous devrez les fournir vous-même en vous basant sur les ?chiers d’en-têtes C tels que <sys/ioctl.h>. (Il existe un
script Perl appelé h2ph qui vient avec le kit Perl et qui devrait vous aider à faire cela mais il n’est pas trivial.) SCALAIRE sera
lu et/ou modi?é selon la fonction FONCTION – un pointeur sur la valeur alphanumérique de SCALAIRE est passé comme
troisième argument du vrai appel système ioctl(). (Si SCALAIRE n’a pas de valeur alphanumérique mais a une valeur
numérique, c’est cette valeur qui sera passée plutôt que le pointeur sur la valeur alphanumérique. Pour garantir que c’est bien
ce qui se passera, ajouter 0 au scalaire avant de l’utiliser.) Les fonction pack() et unpack() permettent de manipuler les
différentes structures utilisées par ioctl().
Les différentes valeurs retournées par ioctl (et fcntl) sont les suivantes :
93

7.1. DESCRIPTION
perlfunc
si l’OS retourne :
alors Perl retournera :
-1
la valeur indéfinie (undef)
0
la chaîne "0 but true"
autre nombre
ce nombre
Ainsi Perl retourne vrai en cas de succès et faux en cas d’échec et vous pouvez encore déterminer la véritable valeur retourné
par le système d’exploitation :
$retval = ioctl( ) || -1;
printf "System returned %d\n", $retval;
La chaîne spéciale "0 but true" est traitée par -w comme une exception qui ne déclenche pas le message d’avertissement
concernant les conversions numériques incorrectes.
Voici un exemple qui rend non-bloquant au niveau système le descripteur de ?chier REMOTE. En revanche, vous aurez à gérer
vous-même le traitement de $|.
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
$flags = fcntl(REMOTE, F_GETFL, 0)
or die "Can’t get flags for the socket: $!\n";
$flags = fcntl(REMOTE, F_SETFL, $flags | O_NONBLOCK)
or die "Can’t set flags for the socket: $!\n";
join EXPR,LISTE
Concatène les différentes chaînes de LISTE en une seule chaîne où les champs sont séparés par la valeur de EXPR et retourne
cette nouvelle chaîne. Exemple :
$_ = join(’:’, $login,$passwd,$uid,$gid,$gcos,$home,$shell);
Au contraire de split, join ne prend pas un motif comme premier argument. À comparer à le titre split dans ce document.
keys HASH
Retourne une liste constituée de toutes les clés (en anglais : keys) de la table de hachage fournie. (Dans un contexte scalaire,
retourne le nombre de clés.) Les clés sont produites dans un ordre apparemment aléatoire. Cet ordre particulier pourrait
changer dans une version future mais il est garanti que ce sera toujours le même que celui produit par les fonctions values()
ou each() (en supposant que la table de hachage n’a pas été modi?ée). Un effet de bord est la réinitialisation de l’itérateur de
HASH.
Voici encore une autre manière d’af?cher votre environnement :
@keys = keys %ENV;
@values = values %ENV;
while (@keys) {
print pop(@keys), ’=’, pop(@values), "\n";
}
et comment trier tout cela par ordre des clés :
foreach $key (sort(keys %ENV)) {
print $key, ’=’, $ENV{$key}, "\n";
}
Pour trier une table de hachage par valeur, vous aurez à utiliser la fonction sort(). Voici le tri d’une table de hachage par
ordre décroissant de ses valeurs :
foreach $key (sort { $hash{$b} <=> $hash{$a} } keys %hash) {
printf "%4d %s\n", $hash{$key}, $key;
}
En tant que lvalue (valeur modi?able), keys() vous permet de d’augmenter le nombre de réceptacles alloués pour la table de
hachage concernée. Cela peut améliorer les performances lorsque vous savez à l’avance qu’une table va grossir. (C’est tout à
fait similaire à l’augmentation de taille d’un tableau en affectant une grande valeur à $#tableau.) Si vous dites :
keys %hash = 200;
94

7.1. DESCRIPTION
perlfunc
alors %hash aura au moins 200 réceptacles alloués – 256 en fait, puisque la valeur est arrondie à la puissance de deux im-
médiatement supérieure. Ces réceptacles seront conservés même si vous faites %hash = (). Utilisez undef %hash si vous
voulez réellement libérer l’espace alloué. En revanche, vous ne pouvez pas utiliser cette méthode pour réduire le nombre de
réceptacles alloués (n’ayez aucune inquiétude si vous le faites tout de même par inadvertance : cela n’a aucun effet).
Voir aussi each, values et sort.
kill SIGNAL, LISTE
Envoie un signal à une liste de processus. Retourne le nombre de processus qui ont été correctement « signalés » (qui n’est
pas nécessairement le même que le nombre de processus à qui le signal a été envoyé).
$cnt = kill 1, $child1, $child2;
kill 9, @goners;
Si SIGNAL vaut zéro, aucun signal n’est envoyé. C’est un moyen pratique de véri?er qu’un process existe encore et n’a pas
changé son UID. Voir le manuel perlport pour véri?er la portabilité d’une telle construction.
Au contraire du shell, en Perl, si SIGNAL est négatif, il « kill » le groupe de processus plutôt que les processus. (Sur System V,
un numéro de PROCESSUS négatif « kill » aussi les groupes de processus mais ce n’est pas portable.) Cela signi?e que vous
utiliserez habituellement une valeur positive comme signal. Vous pouvez aussi utilisez un nom de signal entre apostrophes.
Voir le titre Signaux dans le manuel perlipc pour tous les détails.
last LABEL
last
La commande last est comme l’instruction break en C (telle qu’elle est utilisée dans les boucles) ; cela permet de sortir
immédiatement de la boucle en question. En l’absence de LABEL, la commande se réfère à la boucle englobante la plus
profonde. Le bloc continue, si il existe, n’est pas exécuté :
LINE: while (<STDIN>) {
last LINE if /^$/;
# exit when done with header
#
}
last ne peut pas être utilisé pour sortir d’un bloc qui doit retourner une valeur comme eval {}, sub {} ou do {} et ne
devrait pas être utilisé pour sortir d’une opération grep() ou map().
Notez qu’un bloc en lui-même est sémantiquement équivalent à une boucle qui ne s’exécuterait qu’une seule fois. Par consé-
quent, last peut être utilisé pour sortir prématurément d’un tel bloc.
Voir aussi le titre continue dans ce document pour une illustration du comment marche last, next et redo.
lc EXPR
lc
Retourne une version de EXPR entièrement en minuscules. C’est la fonction interne qui implémente le séquence d’échap-
pement \L dans les chaînes entre guillemets. Respecte le locale courant LC_CTYPE si use locale est actif. Voir le manuel
perllocale.
En l’absence de EXPR, s’applique à $_.
lc?rst EXPR
lc?rst
Retourne un version de EXPR avec le premier caractère en minuscule. C’est la fonction interne qui implémente le séquence
d’échappement \l dans les chaînes entre guillemets. Respecte le locale courant LC_CTYPE si use locale est actif. Voir le
manuel perllocale.
En l’absence de EXPR, s’applique à $_.
length EXPR
length
Retourne la longueur en octets de la valeur de EXPR. En l’absence de EXPR, s’applique à $_. Notez que cette fonction
ne s’applique ni à un tableau ni à une table de hachage pour savoir combien d’éléments ils contiennent. Pour cela, utilisez
respectivement scalar @tableau et scalar keys %hash
link OLDFILE,NEWFILE
Créer un nouveau ?chier NEWFILE lié à l’ancien ?chier OLDFILE. Retourne true (vrai) en cas de succès ou false (faux)
sinon.
listen SOCKET,QUEUESIZE
Fait exactement la même chose que l’appel système du même nom. Retourne true (vrai) en cas de succès ou false (faux) sinon.
Voir les exemples dans le titre Sockets : Communication Client/Serveur dans le manuel perlipc.
95

7.1. DESCRIPTION
perlfunc
local EXPR
Vous devriez certainement utiliser my() à la place car local() n’a pas la sémantique que la plupart des gens accorde à la
notion « local ». Voir le titre Variables Privées via my() dans le manuel perlsub pour plus de détails.
local() modi?e les variables listées pour qu’elles soient locales au bloc/?chier/eval englobant. Si plus d’une valeur est
donnée, la liste doit être placée entre parenthèses. Voir le titre Valeurs Temporaires via local() dans le manuel perlsub pour plus
de détails, en particulier tout ce qui touchent aux tables de hachage et aux tableaux liés (par tie()).
localtime EXPR
Convertit une date telle que retournée par le fonction time en un tableau de 9 éléments avec la date liée au fuseau horaire local.
On l’utilise typiquement de la manière suivante :
#
0
1
2
3
4
5
6
7
8
($sec,$min,$heure,$mjour,$mois,$annee,$sjour,$ajour,$isdst) =
localtime(time);
Tous les éléments du tableau sont numériques et restent tels qu’ils apparaissent dans la structure ’struct tm’. $sec, $min et
$heure sont les secondes, les minutes et l’heure de l’instant spéci?é. $mjour est le quantième du mois et $mois est le mois
lui-même, dans l’intervalle 0..11 avec 0 pour janvier et 11 pour décembre. $annee est le nombre d’années depuis 1900 et
donc $annee vaut 123 en l’an 2023. $sjour est le jour de la semaine avec 0 pour le dimanche et 3 pour le mercredi. $ajour
est le jour de l’année dans l’intervalle 1..365 (ou 1..366 pour les années bissextiles.) $isdst est vrai si l’heure d’été est en
cours à la date spéci?ée et faux sinon.
Remarquez bien que $annee n’est pas que les deux derniers chiffres de l’année. Si vous supposez cela, vous créez des pro-
grammes non compatible an 2000 – et vous ne voulez pas faire cela, n’est-ce pas ?
La bonne méthode pour obtenir une année complète sur 4 chiffres est tout simplement :
$annee += 1900;
Et pour obtenir les deux derniers chiffres de l’année (e.g. ’01’ en 2001):
$annee = sprintf("%02d", $annee % 100);
En l’absence de EXPR, localtime() utilise la date courante (localtime(time)).
Dans un contexte scalaire, retourne la valeur de ctime(3) :
$now_string = localtime;
# e.g., "Thu Oct 13 04:54:34 1994"
La valeur scalaire n’est pas dépendante du locale, voir le manuel perllocale, mais est construite de manière interne à Perl.
Voir aussi le module Time::Local et les fonctions strftime(3) et mktime(3) du module POSIX. Pour obtenir quelque chose de
similaire mais dont les chaînes de caractères des dates dépendent du locale, paramétrez vos variables d’environnement liées
au locale (voir le manuel perllocale) et essayez par exemple :
use POSIX qw(strftime);
$now_string = strftime "%a %b %e %H:%M:%S %Y", localtime;
Notez que %a et %b, les formes courtes du jour de la semaine et du mois de l’année, n’ont pas obligatoirement 3 caractères de
long.
lock
lock I<CHOSE>
Cette fonction place un verrou coopératif sur une variable, une subroutine ou un objet référencé contenu dans CHOSE jusqu’à
ce que lock sorte de la portée du programme. C’est une fonction interne uniquement si votre version de Perl a été construite
avec le multi-thread activé et si vous avez dit use Threads. Sinon, c’est la fonction du même nom dé?nie par l’utilisateur qui
est appelée. Voir le manuel Thread.
log EXPR
log
Retourne le logarithme népérien ou naturel (base e) de EXPR. En l’absence de EXPR, retourne le log de $_. Pour obtenir le
logarithme dans une autre base, utilisez la propriété suivante : le logarithme en base N d’un nombre est égal au logarithme
naturel de ce nombre divisé par le logarithme naturel de N. Par exemple :
sub log10 {
my $n = shift;
return log($n)/log(10);
}
96

7.1. DESCRIPTION
perlfunc
Voir le titre exp dans ce document pour l’opération inverse.
lstat DESCRIPTEUR
lstat EXPR
lstat
Fait la même chose que la fonction stat() (y compris de modi?er le descripteur spécial _) mais fournit les données du lien
symbolique au lieu de celles du ?chier pointé par le lien. Si les liens symboliques ne sont pas implémentés dans votre système,
un appel normal à stat() est effectué.
En l’absence de EXPR, utilise $_.
m//
L’opérateur de correspondance (d’expressions rationnelles). Voir le manuel perlop.
map BLOC LISTE
map EXPR,LISTE
Évalue le bloc BLOC ou l’expression EXPR pour chaque élément de LISTE (en affectant localement chaque élément à $_) et
retourne la liste de valeurs constituée de tous les résultats de ces évaluations. L’évaluation du bloc BLOC ou de l’expression
EXPR a lieu dans un contexte de liste si bien que chaque élément de LISTE peut produire zéro, un ou plusieurs éléments
comme valeur retournée.
@chars = map(chr, @nums);
transcrit une liste de nombres vers les caractères correspondants. Et :
%hash = map { getkey($_) => $_ } @array;
est juste une manière rigolote de dire :
%hash = ();
foreach $_ (@array) {
$hash{getkey($_)} = $_;
}
Remarquez que du fait que $_ est une référence vers la liste de valeurs, il peut être utilisé pour modi?er les éléments du
tableau. Bien que cela soit pratique et supporté, cela peut produire des résultats bizarres si LISTE n’est pas un tableau nommé.
L’utilisation d’une boucle foreach est plus claire dans de nombreux cas. Voir aussi le titre grep dans ce document pour
produire un tableau composé de tous les éléments de la liste originale pour lesquels BLOC ou EXPR est évalué à vrai (true).
mkdir FILENAME,MASK
mkdir
Crée le répertoire dont le nom est spéci?é par FILENAME avec les droits d’accès spéci?és par MASK (et modi?és par umask).
En cas de succès, retourne TRUE (vrai). Sinon, retourne false (faux) et positionne la variable $! (errno). Par défaut, MASK
vaut 0777.
En général, il vaut mieux créer des répertoires avec un MASK permissif et laisser l’utilisateur modi?er cela via son umask que
de fournir un MASK trop restrictif ne permettant pas à l’utilisateur d’être plus permissif. L’exception à cette règle concerne
les répertoires ou les ?chiers doivent être privés (?chiers de messagerie par exemple). /umask discute plus en détails du choix
de MASK.
msgctl ID,CMD,ARG
Appelle la fonction msgctl(2) des IPC System V. Vous devrez probablement dire :
use IPC::SysV;
au préalable pour avoir les dé?nitions correctes des constantes. Si CMD est IPC_STAT alors ARG doit être une variable qui
pourra contenir la structure msqid_ds retournée. Renvoie la même chose que ioctl() : la valeur undef en cas d’erreur,
"0 but true" pour la valeur zéro ou la véritable valeur dans les autres cas. Voir aussi la documentation de IPC::SysV et
IPC::Semaphore::Msg.
msgget KEY,FLAGS
Appelle la fonction msgget(2) des IPC System V. Retourne l’id de la queue de messages ou la valeur undef en cas d’erreur.
Voir aussi IPC::SysV et IPC::SysV::Msg.
msgrcv ID,VAR,SIZE,TYPE,FLAGS
Appelle la fonction msgrcv des IPC System V pour recevoir un message à partir de la queue de message d’identi?cateur ID
et le stocker dans la variable VAR avec une taille maximale de SIZE. Remarquez que, si un message est reçu, le type de
message sera la première chose dans VAR et que la taille maximale de VAR est SIZE plus la taille du type de message. Ces
données compactées peuvent être décompactées par unpack("l! a*"). Souille la variable VAR. Retourne TRUE (vrai) en
cas de succès ou false (faux) sinon. Voir aussi IPC::SysV et IPC::SysV::Msg.
97

7.1. DESCRIPTION
perlfunc
msgsnd ID,MSG,FLAGS
Appelle la fonction msgsnd des IPC System V pour envoyer le message MSG dans la queue de messages d’identi?cateur
ID. MSG doit commencer par l’entier long natif donnant le type de message suivi de la longueur réelle du message suivi du
message lui-même. Cette donnée compactée peut être produite par pack("l! a*", $type, $message). Retourne true (vrai)
en cas de succès ou false (faux) en cas d’erreur. Voir aussi IPC::SysV et IPC::SysV::Msg.
my EXPR
my EXPR : ATTRIBUTS
my() déclare les variables listées comme étant locales (lexicalement) au bloc, ?chier ou eval() englobant. Si plus d’une
variable est listée, la liste doit être placée entre parenthèses. Voir le titre Variables Privées via my() dans le manuel perlsub
pour plus de détails.
next LABEL
next
La commande next fonctionne comme l’instruction continue du C ; elle commence la prochaine itération d’une boucle :
LINE: while (<STDIN>) {
next LINE if /^#/;
# ne pas traiter les commentaires
#
}
Si il y avait un bloc continue dans cet exemple, il serait exécuté même pour les lignes ignorées. Si LABEL est omis, la
commande se réfère au bloc englobant le plus intérieur.
next ne peut pas être utilisé pour sortir d’un bloc qui doit retourner une valeur comme eval {}, sub {} ou do {} et ne
devrait pas être utilisé pour sortir d’une opération grep() ou map().
Voir aussi le titre continue dans ce document pour voir comment last, next et redo fonctionne.
no Module LISTE
Voir la fonction le titre use dans ce document pour laquelle no est le contraire.
oct EXPR
oct
Interprète EXPR comme une chaîne octale et retourne la valeur correspondante. (Si il s’avère que EXPR commence par 0x, elle
sera interprétée comme un chaîne hexadécimale. Si EXPR commence par 0b, elle sera interprétée comme une chaîne binaire.)
La ligne suivante manipule les chaîne décimales, binaires, octales et hexadécimales comme le fait la notation standard Perl ou
C :
$val = oct($val) if $val =~ /^0/;
Si EXPR est absent, la commande s’applique à $_. Pour réaliser l’opération inverse (produire la représentation octale d’un
nombre), utilisez sprintf() ou printf() :
$perms = (stat("filename"))[2] & 07777;
$oct_perms = sprintf "%lo", $perms;
La fonction oct() est couramment utilisée pour convertir une chaîne telle que 644 en un mode d’accès pour ?chier par exemple.
(perl convertit automatiquement les chaînes en nombres si besoin mais en supposant qu’ils sont en base 10.)
open DESCRIPTEUR,MODE,LISTE
open DESCRIPTEUR,EXPR
open DESCRIPTEUR
Ouvre le ?chier dont le nom est donné par EXPR et l’associe à DESCRIPTEUR. Si DESCRIPTEUR est une expression, sa
valeur est utilisée en tant que nom du descripteur à associer. (Ceci est considéré comme une référence symbolique donc use
strict ’refs’ ne devrait pas être actif.)
Si EXPR est omis, la variable scalaire du même nom que le DESCRIPTEUR contient le nom du ?chier. (Remarquez que les
variables lexicales – celles déclarées par my() – ne fonctionnent pas dans ce cas ; donc si vous utilisez my(), spéci?ez EXPR
dans votre appel à open.) Voir le manuel perlopentut pour une initiation à l’ouverture de ?chiers.
Si MODE est ’<’ ou rien du tout, le ?chier est ouvert en lecture. Si MODE est ’>’, le ?chier est tronqué puis ouvert en
écriture en étant créé si nécessaire. Si MODE est ’>>’, le ?chier est ouvert en écriture et en mode ajout. Là encore, il sera créé
si nécessaire. Vous pouvez ajouter un ’+’ devant ’>’ ou ’<’ pour indiquer que vous voulez à la fois les droits d’écriture et de
lecture sur le ?chier; ceci étant ’+<’ est toujours mieux pour les mises à jour en lecture/écriture – le mode ’+>’ écraserait le
?chier au préalable. Habituellement, il n’est pas possible d’utiliser le mode lecture/écriture pour des ?chiers textes puisqu’ils
98

7.1. DESCRIPTION
perlfunc
ont des tailles d’enregistrements variables. Voir l’option -i dans le manuel perlrun pour une meilleure approche. Le ?chier est
créé avec les droits 0666 modi?és par la valeur de umask.
Ces différents pré?xes correspondent aux différents modes d’ouverture de fopen(3) : ’r’, ’r+’, ’w’, ’w+’, ’a’ et ’a+’.
Dans sa forme à 1 ou 2 arguments, le mode et le nom de ?chier peuvent être concaténés (dans cet ordre), éventuellement
séparés par des espaces. Il est possible d’omettre le mode si c’est ’<’.
Si le nom de ?chier commence par ’|’, le nom de ?chier est interprété comme une commande vers laquelle seront dirigées
les sorties (via un tube – en anglais pipe) et si le nom de ?chier se termine par ’|’, le nom de ?chier est interprété comme une
commande dont la sortie sera récupérée (via un tube – en anglais pipe). Voir le titre Utilisation de open() pour la CIP dans le
manuel perlipc pour des exemples à ce sujet. (Vous ne pouvez pas utilisez open() pour une commande qui utiliserait un même
tube à la fois pour ses entrées et pour ses sorties mais le manuel IPC::Open2, le manuel IPC::Open3 et le titre Communication
Bidirectionnelle avec un autre Processus dans le manuel perlipc proposent des solutions de remplacement.)
Ouvrir ’-’ revient à ouvrir STDIN tandis qu’ouvrir ’>-’ revient à ouvrir STDOUT.
Open renvoie une valeur non nulle en cas de succès et undef sinon. Si open() utilise un tube, la valeur de retour sera le PID
du sous-processus.
Si, par malheur, vous utilisez Perl sur un système qui fait une distinction entre les ?chiers textes et les ?chiers binaires (les
systèmes d’exploitation modernes ne font pas de différence) alors vous devriez regarder du côté de le titre binmode dans ce
document pour connaître les astuces à ce sujet. La différence entre les systèmes nécessitant binmode() et les autres réside
dans le format de leurs ?chiers textes. Des systèmes tels que Unix, MacOS et Plan9 qui délimitent leurs lignes par un seul
caractère et qui encode ce caractère en C par "\n" ne nécessitent pas binmode(). Les autres en ont besoin.
À l’ouverture d’un ?chier, c’est généralement une mauvaise idée de continuer l’exécution normale si la requête échoue, ce
qui explique pourquoi open() est si fréquemment utilisé en association avec die(). Même si die() n’est pas ce que voulez
faire (par exemple dans un script CGI où vous voulez récupérer un message d’erreur joliment présenté (il y a des modules qui
peuvent vous aider pour cela)), vous devriez toujours véri?er la valeur retournée par l’ouverture du ?chier. L’une des rares
exceptions est lorsque vous voulez travailler sur un descripteur non ouvert.
Exemples :
$ARTICLE = 100;
open ARTICLE or die "Can’t find article $ARTICLE: $!\n";
while (<ARTICLE>) {
open(LOG, ’>>/usr/spool/news/twitlog’); # (log is reserved)
# si le open échoue, les sorties sont perdues
open(DBASE, ’+<’, ’’)
# ouverture pour mise à jour
or die "Can’t open ’’ for update: $!";
open(DBASE, ’+<’)
# idem
or die "Can’t open ’’ for update: $!";
open(ARTICLE, ’-|’, "caesar <$article")
# décryptage de l’article
or die "Can’t start caesar: $!";
open(ARTICLE, "caesar <$article |")
# idem
or die "Can’t start caesar: $!";
open(EXTRACT, "|sort >/tmp/Tmp$$")
# $$ est notre ID de process
or die "Can’t start sort: $!";
# traitement de la liste des fichiers fournie en argument
foreach $file (@ARGV) {
process($file, ’fh00’);
}
sub process {
my($filename, $input) = @_;
$input++;
# c’est une incrémentation de chaîne
unless (open($input, $filename)) {
print STDERR "Can’t open $filename: $!\n";
return;
}
99

7.1. DESCRIPTION
perlfunc
local $_;
while (<$input>) {
# remarquez l’utilisation de l’indirection
if (/^#include "(.*)"/) {
process($1, $input);
next;
}
#
# ce qu’il faut faire
}
}
Vous pouvez aussi, dans la tradition du Bourne shell, spéci?er une expression EXPR commençant par ’>&’ auquel cas le reste
de la chaîne sera interprété comme le nom d’un descripteur (ou son numéro si c’est une valeur numérique) à dupliquer puis
à ouvrir. Vous pouvez utiliser & après >, >>, <, +>, +>> et +<. Le mode que vous spéci?ez devrait correspondre à celui du
descripteur original. (La duplication d’un descripteur ne prend pas en compte l’éventuel contenu des buffers (tampons) de
stdio (les entrées/sorties standard).)
Voici un script qui sauvegarde, redirige et restaure STDOUT et STDERR :
#!/usr/bin/perl
open(OLDOUT, ">&STDOUT");
open(OLDERR, ">&STDERR");
open(STDOUT, ’>’, "") || die "Can’t redirect stdout";
open(STDERR, ">&STDOUT") || die "Can’t dup stdout";
select(STDERR); $| = 1;
# fonctionnement sans tampon
select(STDOUT); $| = 1;
# fonctionnement sans tampon
print STDOUT "stdout 1\n";
# cela fonctionne aussi
print STDERR "stderr 1\n";
# pour les processus fils
close(STDOUT);
close(STDERR);
open(STDOUT, ">&OLDOUT");
open(STDERR, ">&OLDERR");
print STDOUT "stdout 2\n";
print STDERR "stderr 2\n";
Si vous spéci?ez ’<&=N’, où N est un nombre, alors Perl fera l’équivalent d’un fdopen() en C sur ce descripteur de ?chier ;
c’est plus avare en descripteur de ?chier. Par exemple :
open(DESCRIPTEUR, "<&=$fd")
Remarquez bien que cette fonctionnalité dépend la fonction fdopen() de votre bibliothèque C. Sur la plupart des systèmes
UNIX, fdopen() est connu pour échouer lorsque le nombre de descripteur de ?chiers dépasse une certaine limite, typiquement
255. Si vous avez besoin de descripteurs de ?chiers plus nombreux, vous devriez examiner la possibilité de recompiler Perl en
utilisant la bibliothèque sfio.
Si vous ouvrez un tube (pipe) sur la commande ’-’, i.e. soit ’|-’ soit ’-|’, alors vous faites un fork implicite et la valeur
de retour de open est le PID du processus ?ls pour le processus père et 0 pour le processus ?ls. (Utilisez defined($pid)
pour savoir si le open s’est bien déroulé.) Le descripteur se comporte normalement pour le père mais pour le processus ?ls,
les entrées/sorties sur ce descripteur se font via STDIN/STDOUT. Dans le processus ?ls, le descripteur n’est pas ouvert –
les échanges se font via les nouveaux STDIN ou STDOUT. Cela s’avère utile lorsque vous voulez avoir un contrôle plus ?n
sur la commande exécutée par exemple lorsque vous avez un script setuid et que vous ne voulez pas que le shell traite les
méta-caractères dans les commandes. Les lignes suivantes sont quasiment équivalentes (trois à trois) :
open(FOO, "|tr ’[a-z]’ ’[A-Z]’");
open(FOO, ’|-’, "tr ’[a-z]’ ’[A-Z]’");
open(FOO, "|-") || exec ’tr’, ’[a-z]’, ’[A-Z]’;
open(FOO, "cat -n ’$file’|");
open(FOO, ’-|’, "cat -n ’$file’");
open(FOO, "-|") || exec ’cat’, ’-n’, $file;
100

7.1. DESCRIPTION
perlfunc
Voir le titre Ouvertures Sûres d’un Tube dans le manuel perlipc pour plus d’exemples à ce sujet.
À partir de la version v5.6.0, Perl tente de vider les tampons de tous les ?chiers ouverts en écriture avant toute opération
impliquant un fork mais ce n’est pas supporté sur toutes les plates-formes (voir le manuel perlport). Pour être plus sûr, vous
devriez positionné la variable $| ($AUTOFLUSH en anglais) ou appelé la méthode autoflush() des objets IO::Handle pour
chacun des descripteurs ouverts a?n d’éviter toute perte de données.
Sur les systèmes qui supportent le drapeau fermeture-à-l-exécution (close-on-exec) sur les ?chiers, ce drapeau sera positionné
pour de nouveaux descripteurs de ?chier en fonction de la valeur de $ˆF. Voir le titre $ˆF dans le manuel perlvar.
La fermeture d’un descripteur utilisant un tube (pipe) amène le processus père à attendre que son ?ls se termine puis à retourner
la valeur de statut dans $?.
Le nom de ?chier passé à open dans la forme a 1 ou 2 arguments aura ses éventuels espaces avant et après supprimés et les
caractères de redirection normaux seront respectés. Cette fonctionnalité, connue sous le nom de "ouverture magique", autorise
plein de bonnes choses. Un utilisateur peut spéci?er un nom de ?chier tel que "rsh cat ?le |ou alors vous pouvez modi?er
certains noms de ?chiers selon vos besoins :
$filename =~ s/(.*\.gz)\s*$/gzip -dc < $1|/;
open(FH, $filename) or die "Can’t open $filename: $!";
Utilisez la forme à 3 arguments pour ouvrir un ?chier dont le nom contient des caractères quelconques :
open(FOO, ’<’, $file);
sinon il est nécessaire de protéger les caractères spéciaux et tous les espaces avant et/ou après :
$file =~ s#^(\s)#./$1#;
open(FOO, "< $file\0");
(cela peut ne pas fonctionner sur certains systèmes de ?chier bizarres). Vous devez choisir consciemment entre la forme
magique ou la forme à 3 arguments de open() :
open IN, $ARGV[0];
autorisera l’utilisateur à spéci?er un argument de la forme "rsh cat file |" mais ne marchera pas avec un nom de ?chier
contenant des espaces alors que :
open IN, ’<’, $ARGV[0];
a exactement les limitation inverses.
Si vous voulez un "vrai" open() à la C (voir le manuel open(2) sur votre système) alors vous devriez utiliser la fonction
sysopen() qui ne fait rien de magique. C’est un autre moyen de protéger vos noms de ?chiers de toute interprétation. Par
exemple :
use IO::Handle;
sysopen(HANDLE, $path, O_RDWR|O_CREAT|O_EXCL)
or die "sysopen $path: $!";
$oldfh = select(HANDLE); $| = 1; select($oldfh);
print HANDLE "stuff $$\n");
seek(HANDLE, 0, 0);
print "File contains: ", <HANDLE>;
En utilisant le constructeur du paquetage IO::Handle (ou de l’une de ses sous-classes telles que IO::File ou IO::Socket),
vous pouvez générer des descripteurs anonymes qui ont la même portée que les variables qui gardent une référence sur eux et
qui se ferment automatiquement dès qu’ils sont hors de portée :
use IO::File;
#
sub read_myfile_munged {
my $ALL = shift;
my $handle = new IO::File;
open($handle, "myfile") or die "myfile: $!";
$first = <$handle>
or return ();
# Fermeture automatique ici
mung $first or die "mung failed";
# Ou ici.
return $first, <$handle> if $ALL;
# Ou ici.
$first;
# Ou ici.
}
101

7.1. DESCRIPTION
perlfunc
Voir le titre seek() dans ce document pour de plus amples informations sur le mélange entre lecture et écriture.
opendir DIRHANDLE,EXPR
Ouvre le répertoire nommé par EXPR pour un traitement par readdir(), telldir(), seekdir(), rewinddir() et
closedir(). Retourne true (vrai) en cas de succès. Les DIRHANDLEs ont leur propre espace de noms séparé de celui
des DESCRIPTEURs.
ord EXPR
ord
Retourne la valeur numérique ASCII du premier caractère de EXPR. Si EXPR est omis, utilise $_. Voir le titre chr dans ce
document pour l’opération inverse. Voir le manuel utf8 pour en savoir plus sur Unicode.
our EXPR
Un our déclare les variables listées comme étant des variables globales valides dans la portée d’un bloc englobant, d’un ?chier
ou d’un eval. Il a donc la même portée qu’une déclaration "my" mais ne crée pas de variable locale. Si plus d’une valeur est
listée, la liste doit être placée entre parenthèses. La déclaration our n’a aucun effet sémantique à moins que "use strict vars"
soit actif auquel cas, cela vous permet d’utiliser les variables globales déclarées sans les quali?er par un nom de package.
(Mais seulement dans la portée lexicale de votre déclaration our. En cela, il diffère de "use vars" dont la portée est globale au
package.)
Un déclaration our déclare un variable globale qui sera visible dans toute la portée lexicale de cette déclaration, même entre
différents packages. Le package d’appartenance de la variable est déterminée lors de la déclaration et non lors de l’utilisation.
Cela signi?e que vous aurez les comportements suivants :
package Foo;
our $bar;
# déclare $Foo::bar
$bar = 20;
package Bar;
print $bar;
# affiche 20 (valeur de $Foo:bar)
De multiples déclarations our sont autorisées dans la même portée lexicale si elles sont dans des packages différents. Si elles
sont dans le même package, Perl produira un avertissement si vous lui avez demandé.
use warnings;
package Foo;
our $bar;
# déclare $Foo::bar
$bar = 20;
package Bar;
our $bar = 30;
# déclare $Bar::bar
print $bar;
# affiche 30
our $bar;
# émission d’un avertissement
pack TEMPLATE,LISTE
Prend une liste de valeurs et les transforme en une chaîne en utilisant les règles décrites par TEMPLATE. La chaîne résultante
est la concaténation des valeurs converties. Typiquement, chaque valeur convertie aura sa représentation du niveau machine.
Par exemple, sur une machine 32-bit, un entier converti sera représenté par une séquence de 4 octets.
Le TEMPLATE est une séquence de caractères qui donne l’ordre et le type des valeurs, de la manière suivante :
a
Une chaîne ASCII, complétée par des caractères NUL.
A
Une chaîne ASCII, complétée par des blancs.
Z
Une chaîne (ASCII) terminée par un caractère NUL,
complété par des caractères NUL.
b
Une chaîne de bits (en ordre croissant dans chaque octet,
comme pour vec()).
B
Une chaîne de bits (en ordre décroissant dans chaque octet).
h
Une chaîne hexadécimale (chiffres hexadécimaux faibles en premier).
H
Une chaîne hexadécimale (chiffres hexadécimaux forts en premier).
c
La valeur d’un caractère signé.
C
La valeur d’un caractère non signé. Ne traite que des octets.
Voir U pour Unicode.
102

7.1. DESCRIPTION
perlfunc
s
La valeur d’un entier court (short) signé
S
La valeur d’un entier court (short) non signé
(Ce ’short’ est _exactement_ sur 16 bits ce qui peut
être différent de ce qu’un compilateur C local
appelle ’short’. Si vous voulez un short natif, utilisez
le suffixe ’!’.)
i
La valeur d’un entier (integer) signé.
I
La valeur d’un entier (integer) non signé.
(Cet ’integer’ est _au moins_ sur 32 bits. Sa taille
exact dépend de ce que le compilateur C local appelle ’int’
et peut même être plus long que le ’long’ décrit
à l’item suivant.)
l
La valeur d’un entier long (long) signé.
L
La valeur d’un entier long (long) non signé.
(Ce ’long’ est _exactement_ sur 32 bits ce qui peut
être différent de ce qu’un compilateur C local
appelle ’long’. Si vous voulez un long natif, utilisez
le suffixe ’!’.)
n
Un entier court non signé (short) dans l’ordre "réseau" (big-endian).
N
Un entier long non signé (long) dans l’ordre "réseau" (big-endian).
v
Un entier court non signé (short) dans l’ordre "VAX" (little-endian).
V
Un entier long non signé (long) dans l’ordre "VAX" (little-endian).
(Ces ’shorts’ et ces ’longs’ font _exactement_
16 et 32 bits respectivement.)
q
Une valeur quad (64-bit) signée.
Q
Une valeur quad non signée.
(Les quads ne sont disponibles que si votre système supporte
les entiers 64-bit _et_ que si Perl a été compilé pour les
accepter. Provoquera une erreur fatale sinon.)
f
Un flottant simple précision au format natif.
d
Un flottant double précision au format natif.
p
Un pointeur vers une chaîne terminée par un caractère NUL.
P
Un pointeur vers une structure (une chaîne de longueur fixe).
u
Une chaîne uuencodée.
U
Un code d’un caractère Unicode. Encode en UTF-8 en interne.
Fonctionne même si ’use utf8’ n’est pas actif.
w
Un entier BER compressé. Ses octets représentent chacun un entier
non signé en base 128. Les chiffres les plus significatifs viennent
en premier et il y a le moins de chiffres possibles. Le huitième bit
(le bit de poids fort) est toujours à 1 pour chaque octets sauf
le dernier.
x
Un octet nul.
X
Retour en arrière d’un octet.
@
Remplissage par des octets nuls jusqu’à une position absolue.
Les règles suivantes s’appliquent :
– Chaque lettre peut éventuellement être suivie d’un nombre spéci?ant le nombre de répétition. Pour tous les types (sauf a,
A, Z, b, B, h, H et P), la fonction pack utilisera autant de valeurs de la liste LISTE que nécessaire. Une * comme valeur de
répétition demande à utiliser toutes les valeurs restantes excepté pour @, x et X où c’est équivalent à 0 et pour u où c’est
équivalent à 1 (ou 45, ce qui est la même chose).
Utilisé avec Z, * déclenchera l’ajout d’un octet nul ?nal (donc la valeur compactée sera d’un octet plus long que la longueur
(length) de la valeur initiale).
La valeur de répétition pour u est interprétée comme le nombre maximale d’octets à encoder par ligne produite avec 0 et 1
remplacé par 45.
103

7.1. DESCRIPTION
perlfunc
– Les types a, A et Z n’utilisent qu’une seule valeur mais la compacte sur la longueur spéci?ée en la complétant éventuellement
par des espaces ou des caractères NUL. Lors du décompactage, A supprime les espaces et les caractères NUL ?nals, Z
supprime tout ce qui suit le premier caractère NUL alors que a laisse la valeur complète. Lors du compactage, a et Z sont
équivalents.
Si la valeur à compacter est trop longue, elle est tronquée. Si elle est trop longue et qu’une longueur explicite $count est
fournie, Z compactera uniquement $count-1 octets suivi d’un octet nul. Donc, Z compacte un caractère nul ?nal en toutes
circonstances.
– De la même manière, les types b et B remplissent la chaîne compactée avec autant de bits que demandés. Chaque octet
du champ d’entrée de pack() produira 1 bit dans le résultat. Chaque bit résultant est le bit le moins signi?catif de l’octet
d’entrée (i.e. ord($octet)%2). En particulier, les octets "0" et "1" produisent les bits 0 et 1 exactement comme le font
"\0" et "\1".
En partant du début de la chaîne d’entrée de pack(), chaque 8-uplet d’octets est converti en un octet de sortie. Avec le format
b, le premier octet du 8-uplet détermine le bit le moins signi?catif de l’octet alors qu’avec le format B, il détermine le bit le
plus signi?catif.
Si la longueur de la chaîne d’entrée n’est pas exactement divisible par 8, le reste est compacté comme si la chaîne d’entrée
était complétée par des octets nuls à la ?n. De manière similaire, lors du décompactage, les bits "supplémentaires" sont
ignorés.
Si la chaîne d’entrée de pack() est plus longue que nécessaire, les octets en trop sont ignorés. Une valeur de répétition de *
demande à utiliser tous les octets du champ d’entrée. Lors du décompactage, les bits sont convertis en une chaîne de "0" et
de "1".
– h et H compactent une chaîne hexadécimale (par groupe de 4-bit représentant un chiffre hexadécimale 0-9a-f).
Chaque octet du champ d’entrée de pack() génère 4 bits du résultat. Pour les octets non alphabétiques, le résultat est basé
sur les 4 bits les moins signi?catifs de l’octet considéré (i.e. sur ord($octet)%16). En particulier, les octets "0" et "1"
génèrent 0 et 1 comme le font les octets "\0" et "\1". Pour les octets "a".."f" et "A".."F", le résultat est compatible
avec les chiffres hexadécimaux habituels et donc "a" et "A" génèrent tous les deux le groupe de 4 bits 0xa==10. Le résultat
pour les octets "g".."z" et "G".."Z" n’est pas clairement dé?ni.
En partant du début de la chaîne d’entrée de pack(), chaque paire d’octets est convertie en 1 octet de sortie. Avec le format
h, le premier octet de la paire détermine les 4 bits les moins signi?catifs de l’octet résultant alors qu’avec le format H, il
détermine les 4 bits les plus signi?catifs.
Si la longueur de la chaîne d’entrée n’est pas paire, pack() se comportera comme si un octet nul avait été ajouté à la ?n. De
manière similaire, lors du décompactage (par unpack()), les groupes de 4 bits supplémentaires sont ignorés.
Si la chaîne d’entrée de pack() est plus longue que nécessaire, les octets supplémentaires sont ignorés. Une valeur de
répétition de * demande à utiliser tous les octets de la chaîne d’entrée. Lors du décompactage, les bits sont convertis en une
chaîne de chiffres hexadécimaux.
– Le type "p" compactera une chaîne terminée par un caractère NUL dont on donne le pointeur. Il est de votre responsabilité
de vous assurer que la chaîne n’est pas une valeur temporaire (qui pourrait être désallouée avant l’utilisation de la valeur
compactée). Le type P compactera une structure de la taille indiqué par la longueur. Un pointeur NULL est créé si la valeur
correspondant à "p" ou "P" est undef. Idem pour unpack().
– Le caractère / dans TEMPLATE autorise le compactage et le décompactage de chaîne donc la représentation compacte est
la longueur en octet suivie de la chaîne elle-même. Vous écrivez longueur-item/chaine-item.
longueur-item peut être n’importe quel type de lettre d’un TEMPLATE pack et décrit la manière dont la longueur est
compactée. Les plus courantes sont n (pour les chaînes Java), w (pour ASN.1 ou SNMP) et N (pour les XDR de SUN).
chaine-item doit être, si il est présent, "A*", "a*" ou "Z*". Pour le décompactage (via unpack()), la longueur de la chaîne
est celle obtenue par longueur-item mais si vous spéci?ez ’*’, elle sera ignorée.
unpack ’C/a’, "\04Gurusamy";
donne ’Guru’
unpack ’a3/A* A*’, ’007 Bond
J ’;
donne (’ Bond’,’J’)
pack ’n/a* w/a*’,’hello,’,’world’;
donne "\000\006hello,\005world"
longueur-item n’est pas retourné explicitement par unpack().
L’ajout d’un compteur de répétition à la lettre longueur-item est inutile sauf si cette lettre est A, a ou Z. Le compactage avec
une longueur-item spéci?ée par a ou Z peut introduire des caractères "\000" que Perl ne considérera pas comme légal dans
une chaîne numérique.
– Les types entiers s, S, l et L peuvent être immédiatement suivi d’un suf?xe ! pour indiquer des shorts ou des longs natifs
– comme vous pourrez le voir dans l’exemple suivant, l ne signi?e pas exactement 32 bits puisque le long natif (tel qu’il
est vu par le compilateur C natif) peut être plus long. C’est une préoccupation principalement sur des plates-formes 64-bit.
Vous pouvez voir si l’utilisation de ! fait une différence en faisant :
print length(pack("s")), " ", length(pack("s!")), "\n";
print length(pack("l")), " ", length(pack("l!")), "\n";
i! et I! fonctionne aussi mais uniquement dans un souci de complétude puisqu’ils sont totalement identique à i et I.
La taille réelle (en octets) des short, int, long et long long natifs sur la plate-forme où Perl a été installé est aussi disponible
via le manuel Con?g :
104

7.1. DESCRIPTION
perlfunc
use Config;
print $Config{shortsize},
"\n";
print $Config{intsize},
"\n";
print $Config{longsize},
"\n";
print $Config{longlongsize}, "\n";
($Config{longlongsize} sera indé?ni (undef) si votre système ne supporte pas les long long).
– Les formats entiers s, S, i, I, l et L sont par construction non portables entre processeurs et entre systèmes d’exploitation
puisqu’ils respectent l’ordre (big-endian ou little-endian) natif. Par exemple l’entier sur 4 octets 0x12345678 (305419896
en décimal) sera nativement ordonné (stocké et manipulé par les registres de la CPU) en octets comme :
0x12 0x34 0x56 0x78
# ordre little-endian
0x78 0x56 0x34 0x12
# ordre big-endian
À la base, les CPU des familles Intel, Alpha et VAX sont little-endian alors que tous les autres, par exemple Motorola
m68k/88k, PPC, Sparc, HP PA, Power et Cray, sont big-endian. Les MIPS peuvent être les deux : Digital les utilise en mode
little-endian ; SGI les utilise en mode big-endian.
Les noms "big-endian" et "little-endian" sont des références au grand classique "Les voyages de Gulliver" (au travers de
l’article "On Holy Wars and a Plea for Peace" par Danny Cohen, USC/ISI IEN 137, April 1, 1980) et donc aux habitudes
des mangeurs d’oeufs Lilliputiens.
Quelques systèmes peuvent même avoir un ordre des octets encore plus bizarre tel que :
0x56 0x78 0x12 0x34
0x34 0x12 0x78 0x56
Vous pouvez voir les préférences de votre systèmes par
print join(" ", map { sprintf "%#02x", $_ }
unpack("C*",pack("L",0x12345678))), "\n";
L’ordre des octets de la plate-forme où Perl a été installé est aussi disponible via le manuel Con?g :
use Config;
print $Config{byteorder}, "\n";
Les ordres d’octets ’1234’ et ’12345678’ sont little-endian alors que ’4321’ et ’87654321’ sont big-endian.
Si vous voulez des entiers compactés portables, il vous faut utiliser les formats n, N, v et V puisque leur taille et l’ordre de
leurs octets est connus. Voir aussi le manuel perlport.
– Les nombres réels (simple et double précision) sont uniquement au format natif de la machine. À cause de la multiplicité
des formats existants pour les ?ottants et du manque d’une représentation "réseau" standard, aucune possibilité d’échange
n’est proposée. Cela signi?e que les données réelles compressées sur une machine peuvent ne pas être lisibles par une autre
machine – même si elles utilisent toutes deux l’arithmétique ?ottante IEEE (puisque l’ordre des octets de la représentation
mémoire ne fait pas partie des spéci?cations IEEE). Voir aussi le manuel perlport.
Sachez que Perl utilise des doubles en interne pour tous les calculs numériques et qu’une conversion de double vers ?oat
puis retour vers double amène à une perte de précision (i.e., unpack("f", pack("f", $foo)) est généralement différent
de $foo).
– Vous devez réaliser vous-même tous les alignements et les remplissages nécessaires en insérant par exemple assez de x
lors du compactage. pack() et unpack() n’ont aucun moyen d’où viennent et où iront les octets. Par conséquent, pack() (et
unpack()) gère leurs entrée et leurs sortie comme des séquences d’octets à plat.
– Dans TEMPLATE, un commentaire commence par # et se termine en ?n de ligne.
– Si TEMPLATE nécessite plus d’argument que ceux réellement fournis, pack() supposera que des arguments "" supplémen-
taires sont fournis. Si TEMPLATE nécessite moins d’arguments que ceux réellement fournis à pack(), les arguments en trop
sont ignorés.
Exemples :
$foo = pack("CCCC",65,66,67,68);
# foo eq "ABCD"
$foo = pack("C4",65,66,67,68);
# même chose
$foo = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);
# même chose avec des lettres cerclées Unicode
$foo = pack("ccxxcc",65,66,67,68);
# foo eq "AB\0\0CD"
# note : les exemples précédents utilisant "C" et "c" ne sont
# corrects que sus des systèmes ACSII ou dérivés comme ISO Latin 1
# ou UTF-8. En EBCDIC, le premier exemple devrait être
# $foo = pack("CCCC",193,194,195,196);
$foo = pack("s2",1,2);
105

7.1. DESCRIPTION
perlfunc
# "\1\0\2\0" sur little-endian
# "\0\1\0\2" sur big-endian
$foo = pack("a4","abcd","x","y","z");
# "abcd"
$foo = pack("aaaa","abcd","x","y","z");
# "axyz"
$foo = pack("a14","abcdefg");
# "abcdefg\0\0\0\0\0\0\0"
$foo = pack("i9pl", gmtime);
# une vraie struct tm (sur mon système en tous cas)
$utmp_template = "Z8 Z8 Z16 L";
$utmp = pack($utmp_template, @utmp1);
# une struct utmp (BSD-isme)
@utmp2 = unpack($utmp_template, $utmp);
# "@utmp1" eq "@utmp2"
sub bintodec {
unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}
$foo = pack(’sx2l’, 12, 34);
# short 12, two zero bytes padding, long 34
$bar = pack(’s@4l’, 12, 34);
# short 12, zero fill to position 4, long 34
# $foo eq $bar
La même valeur de TEMPLATE peut généralement être utilisée avec la fonction unpack().
package
package NAMESPACE
Déclare l’unité de compilation comme faisant partie de l’espace de nommage NAMESPACE. La portée de la déclaration
package (N.d.t: paquetage en français) commence à la déclaration elle-même et se termine à la ?n du bloc, du ?chier ou de
l’eval englobant (c’est la même portée que l’opérateur local()). Tout identi?cateur dynamique non quali?é à venir sera dans
cet espace de nommage. Une instruction package n’affecte que que les variables dynamiques – même celles sur lesquelles
vous utilisez local() – et non les variables lexicales créées par my(). C’est typiquement la première déclaration dans un
?chier inclus par les opérateurs require ou use. Vous pouvez basculer vers un même paquetage en plusieurs endroits ; cela
ne fait que changer la table de symboles utilisée par le compilateur pour la suite du bloc. Vous pouvez référencer des variables
ou des descripteurs de ?chiers d’autres packages en pré?xant l’identi?cateur par le nom du package suivi de deux fois deux
points : $Package::Variable. Si le nom de paquetage est vide, c’est la paquetage main qui est utilisé. Donc $::sail est
équivalent à $main::sail (et aussi à $main’sail qui peut encore se voir dans du vieux code)..
Si NAMESPACE est omis alors il n’y a pas de paquetage courant et tous les identi?cateurs doivent être soit complètement
quali?és soit lexicaux. C’est plus strict que use strict puisque cela inclut aussi les noms de fonctions.
Voir le titre Paquetages dans le manuel perlmod pour des plus amples informations à propos des paquetages (packages), des
modules et des classes. Voir le manuel perlsub pour tous les problèmes de portée.
pipe READHANDLE,WRITEHANDLE
Ouvre une paire de tubes (pipe) exactement comme l’appel système correspondant. Remarquez qu’en faisant une boucle de
tubes entre plusieurs processus vous risquez un inter-blocage (deadlock) à moins d’y faire très attention. De plus, sachez
que les tubes de Perl utilisent les tampons (buffers) de stdio. Donc, selon les applications, vous aurez peut-être à positionner
correctement $| pour vider vos WRITEHANDLE après chaque commande.
Voir le manuel IPC::Open2, le manuel IPC::Open3 et le titre Communication Bidirectionnelle avec un autre Processus dans
le manuel perlipc pour des exemples sur tout ça.
Sur les systèmes qui supportent le drapeau fermeture-à-l-exécution (close-on-exec) sur les ?chiers, ce drapeau sera positionné
pour de nouveaux descripteurs de ?chier en fonction de la valeur de $ˆF. Voir le titre $ˆF dans le manuel perlvar.
pop TABLEAU
pop
Dépile et retourne la dernière valeur du tableau TABLEAU. La taille du tableau est diminué d’une unité. Cette commande a le
même effet que :
106

7.1. DESCRIPTION
perlfunc
$TABLEAU[$#TABLEAU--]
Si le tableau est vide, c’est la valeur undef qui est retournée (cela peut arriver dans d’autres cas aussi). Si TABLEAU est omis,
pop dépilera soit le tableau @ARGV dans le programme principale soit @_ dans les subroutines, exactement comme shift().
pos SCALAIRE
pos
Retourne l’offset (l’index du caractère dans la chaîne) où s’est arrêté la dernière recherche m//g sur la variable SCALAIRE
spéci?ée (s’appliquera à $_ si la variable SCALAIRE n’est pas spéci?ée). Peut être utilisé pour modi?er cette offset. Une
telle modi?cation in?ue aussi sur l’assertion de longueur nulle \G dans les expressions rationnelles. Voir le manuel perlre et le
manuel perlop.
print DESCRIPTEUR LISTE
print LISTE
print
Af?che une chaîne ou une liste de chaînes. Retourne true (vrai) en cas de succès. DESCRIPTEUR peut être une variable sca-
laire auquel cas cette variable contiendra le nom ou la référence du DESCRIPTEUR et donc introduira un niveau d’indirection
supplémentaire. (REMARQUE: si DESCRIPTEUR est une variable et que l’élément syntaxique qui suit est un terme, il peut
être interprété accidentellement comme un opérateur à moins d’ajouter un + ou de mettre des parenthèses autour des argu-
ments.) Si DESCRIPTEUR n’est spéci?é, af?chera par défaut sur la sortie standard (ou le dernier canal de sortie sélectionné
– voir le titre select dans ce document). Si la liste LISTE est elle aussi omise, af?chera $_ sur le canal de sortie courant. Pour
utiliser un autre canal que STDOUT comme canal de sortie par défaut, utilisez l’opération select. La valeur courante de $,
(si elle existe) est af?chée entre chaque item de LISTE. Remarquez qu’étant donné que print utilise une liste (LISTE), tout ce
qui est dans LISTE est évalué dans un contexte de liste et, en particulier, toutes les expressions évaluées dans les subroutines
appelées le seront dans un contexte de liste. Faites aussi attention de ne pas faire suivre le mot-clé print par une parenthèse
ouvrante à moins de vouloir clore la liste de ses arguments à la parenthèse fermante correspondante – sinon pré?xez votre
parenthèse par un + ou entourez tous les arguments par des parenthèses.
Notez que si vous stockez vos DESCRIPTEUR dans un tableau (ou quelque chose qui nécessite une expression), vous devrez
utiliser un bloc qui retourne une valeur :
print { $files[$i] } "stuff\n";
print { $OK ? STDOUT : STDERR } "stuff\n";
printf DESCRIPTEUR FORMAT, LISTE
printf FORMAT, LISTE
Équivalent à print DESCRIPTEUR sprintf(FORMAT, LISTE) sauf que $\ (le séparateur d’enregistrements en sortie) n’est
pas ajouté. Le premier argument de la liste sera interprété comme le format de printf(). Si use locale est actif, le caractère
utilisé comme séparateur décimal pour les nombres réels sera dépendant de la valeur de locale spéci?ée dans LC_NUMERIC.
Voir le manuel perlocale.
Ne tomber pas de le piège d’utiliser printf() alors qu’un simple print() suf?rait. print() est plus ef?cace et moins sujet
à erreur.
prototype FONCTION
Retourne, sous forme de chaîne, le prototype d’une fonction (ou undef si la fonction n’a pas de prototype). FONCTION est
une référence ou le nom de la fonction dont on veut retrouver le prototype.
Si FONCTION est une chaîne commençant par CORE::, la suite de la chaîne se réfère au nom d’une fonction interne de Perl.
Si la fonction interne n’est pas redé?nissable (par exemple qw//) ou si ses arguments ne peuvent s’exprimer sous forme de
prototype (par exemple system()) - en d’autres termes, si la fonction interne ne se comporte pas comme une fonction Perl -
la fonction prototype retournera undef. Sinon, c’est la chaîne qui décrit le prototype qui est retournée.
push TABLEAU,LISTE
Traite TABLEAU comme une pile et empile les valeurs de la liste LISTE à la ?n du tableau TABLEAU. La longueur de
TABLEAU est augmentée de la longueur de la liste LISTE. Cela a le même effet que :
for $value (LISTE) {
$TABLEAU[++$#TABLEAU] = $value;
}
mais en plus ef?cace. Retourne le nouveau nombre d’éléments du tableau.
q/CHAINE/
qq/CHAINE/
qr/CHAINE/
107

7.1. DESCRIPTION
perlfunc
qx/CHAINE/
qw/CHAINE/
Guillemets/Apostrophes généralisées. Voir le manuel perlop.
quotemeta EXPR
quotemeta
Retourne la valeur de EXPR avec tous les caractères non alphanumériques précédés par un backslash (une barre oblique
inverse). (Tous les caractères non reconnus par /[A-Za-z_0-9]/ seront précédés d’un backslash quelques soient les réglages
des locale). C’est la fonction interne qui implémente la séquence d’échappement \Q dans les chaînes entre guillemets.
Si EXPR est omis, s’appliquera à $_.
rand EXPR
rand
Retourne un nombre fractionnaire aléatoire plus grand ou égal à 0 et plus petit que la valeur de EXPR (la valeur de EXPR
devrait être positive). À défaut de EXPR, c’est 1 qui est utilisé comme borne. Appelle automatiquement srand() sauf cela a
déjà été fait. Voir aussi srand().
(Remarque: si votre fonction rand retourne régulièrement des nombres trop grands ou trop petits alors votre version de Perl a
probablement été compilée avec une valeur erronée pour RANDBITS.)
read DESCRIPTEUR,SCALAIRE,LONGUEUR,OFFSET
read DESCRIPTEUR,SCALAIRE,LONGUEUR
Essaye de lire LONGUEUR octets depuis le DESCRIPTEUR spéci?é et les stocke dans la variable SCALAIRE. Retourne
le nombre d’octets réellement lus, 0 à la ?n du ?chier ou undef si une erreur a lieu. La taille de la variable SCALAIRE
augmentera ou diminuera pour atteindre la taille exacte de ce qui est lu. Un OFFSET (décalage) peut être spéci?é pour placer
les données lues ailleurs qu’au début de la chaîne. Cette fonction est implémentée par des appels à la fonction fread(3) de
stdio. Pour obtenir un véritable appel système read(2), voir sysread().
readdir DIRHANDLE
Retourne l’entrée suivante d’un répertoire ouvert par opendir(). Dans un contexte de liste, retournera toutes les entrées
restant dans le répertoire. Si il n’y a plus d’entrée, retournera la valeur undef dans un contexte scalaire ou une liste vide dans
un contexte de liste.
Si vous prévoyez de faire des tests de ?chiers sur les valeurs retournées par readdir(), n’oubliez pas de les pré?xer par le
répertoire en question. Sinon, puisqu’aucun appel à chdir() n’est effectué, vous risquez de tester un mauvais ?chier.
opendir(DIR, $some_dir) || die "can’t opendir $some_dir: $!";
@dots = grep { /^\./ && -f "$some_dir/$_" } readdir(DIR);
closedir DIR;
readline EXPR
Lit à partir du descripteur dont le typeglob est donné par EXPR. Dans un contexte scalaire, chaque appel lit et retourne la ligne
suivante jusqu’à atteindre la ?n du ?chier. À ce moment, un appel supplémentaire retournera undef. Dans un contexte de liste,
la lecture se fera jusqu’à la ?n du ?chier et le résultat sera une liste de lignes. La notion de "ligne" utilisée ici est celle dé?nie
par la variable $/ ou $INPUT_RECORD_SEPARATOR. Voir le titre $/ dans le manuel perlvar.
Lorsque $/ est positionné à undef, que readline() est utilisé dans un contexte scalaire (i.e. en mode ’slurp’) et que le ?chier lu
est vide, le premier appel retourne ” et undef pour les suivants.
C’est la fonction interne qui implémente l’opérateur <EXPR> mais vous pouvez l’utiliser directement. L’opérateur <EXPR> est
décrit en détail dans le titre Les opérateurs d’E/S dans le manuel perlop.
$line = <STDIN>;
$line = readline(*STDIN);
# même chose
readlink EXPR
readlink
Retourne la valeur d’un lien symbolique si les liens symboliques sont implémentés. Sinon, produit une erreur fatale. Si il
y a une erreur système, cette fonction retournera la valeur undef et positionnera la variable $! (errno). Si EXPR est omis,
s’applique à $_.
readpipe EXPR
EXPR est exécuté comme une commande système. La sortie standard de la commande est collectée puis retournée. Dans
un contexte scalaire, cette sortie est une seule chaîne (contenant éventuellement plusieurs lignes). Dans un contexte de liste,
retourne une liste de lignes (telles que dé?nies par la variable $/ ou $INPUT_RECORD_SEPARATOR). C’est la fonction interne
qui implémente l’opérateur qx/EXPR/ mais vous pouvez l’utiliser directement. L’opérateur qx/EXPR/ est décrit plus en détail
dans le titre Les opérateurs d’E/S dans le manuel perlop.
108

7.1. DESCRIPTION
perlfunc
recv SOCKET,SCALAIRE,LONGUEUR,FLAGS
Reçoit un message depuis un socket. Tente de recevoir LONGUEUR octets de données dans la variable SCALAIRE depuis
le descripteur spéci?é par SOCKET. SCALAIRE grossira ou réduira jusqu’à la taille des données réellement lues. Utilise les
mêmes FLAGS que l’appel système du même nom. Retourne l’adresse de l’émetteur si le protocole de SOCKET le permet ;
retourne une chaîne vide sinon. Retourne la valeur undef en cas d’erreur. Cette fonction est implémentée en terme d’appel
système recvfrom(2). Voir le titre UDP : Transfert de Message dans le manuel perlipc pour des exemples.
redo LABEL
redo
La commande redo redémarre une boucle sans évaluer à nouveau la condition. Le bloc continue, s’il existe, n’est pas
évalué. Si l’étiquette LABEL est omise, la commande se réfère à la boucle englobante la plus profonde. Cette commande est
habituellement utilisée par des programmes qui veulent utiliser eux-mêmes ce qui vient juste d’être lu :
# un programme simple pour supprimer les commentaires en Pascal
# (Attention: suppose qu’il n’y pas de { ni de } dans les chaînes.)
LINE: while (<STDIN>) {
while (s|({.*}.*){.*}|$1 |) {}
s|{.*}| |;
if (s|{.*| |) {
$front = $_;
while (<STDIN>) {
if (/}/) {
# end of comment?
s|^|$front\{|;
redo LINE;
}
}
}
print;
}
redo ne peut pas être utilisé pour redémarrer un bloc qui doit retourner une valeur comme eval {}, sub {} ou do {} et ne
devrait pas être utilisé pour sortir d’une opération grep() ou map().
Remarques qu’un bloc en lui-même est sémantiquement identique à une boucle qui ne s’exécute qu’une fois. Donc redo dans
un tel bloc le transforme effectivement en une construction de boucle.
Voir aussi le titre continue dans ce document pour illustrer la manière dont last, next et redo fonctionnent.
ref EXPR
ref
Retourne une valeur true (vraie) si EXPR est une référence, false (faux) sinon. Si EXPR n’est pas spéci?é, s’applique à $_. La
valeur retournée dépend du type de ce qui est référencé par la référence. Les types internes incluent :
SCALAR
ARRAY
HASH
CODE
REF
GLOB
LVALUE
Si l’objet référencé a été béni (par bless()) par un paquetage alors le nom du paquetage est retourné. Vous pouvez voir ref()
comme une sorte d’opérateur typeof() (type de).
if (ref($r) eq "HASH") {
print "r is a reference to a hash.\n";
}
unless (ref($r)) {
print "r is not a reference at all.\n";
}
if (UNIVERSAL::isa($r, "HASH")) {
# for subclassing
print "r is a reference to something that isa hash.\n";
}
Voir aussi le manuel perlref.
109

7.1. DESCRIPTION
perlfunc
rename ANCIENNOM,NOUVEAUNOM
Change le nom d’un ?chier ; un ?chier préexistant de nom NOUVEAUNOM sera écrasé. Retourne true (vrai) en cas de succès
ou false (faux) sinon.
Le comportement de cette fonction varie beaucoup d’un système à l’autre. Par exemple, habituellement elle ne fonctionne pas
entre des systèmes de ?chiers différents même si la commande système mv réussit parfois à le faire. Il y a d’autres restrictions
selon que cela fonctionne ou non sur des répertoires, sur des ?chiers ouverts ou sur des ?chiers préexistants. Regarder le
manuel perlport et la page de documentation de rename(2) pour les détails.
require VERSION
require EXPR
require
Exige une « sémantique » spéci?ée par EXPR ou par $_ si EXPR n’est pas fourni.
Si VERSION est spéci?ée comme une chaîne de la forme v5.6.1, exige que la version courante de Perl ($ˆV ou
$PERL_VERSION) soit au moins aussi récente que cette VERSION, lors de l’exécution. (Pour des raisons de compatibi-
lité avec les vieilles version de Perl, un argument numérique sera aussi interprété comme une VERSION). Comparez avec le
titre use dans ce document qui peut faire un contrôle similaire mais lors de la compilation.
require v5.6.1;
# contrôle de version à l’exécution
require 5.6.1;
# idem
require 5.005_03;
# argument numérique autorisé par compatibilité
Sinon, exige que le ?chier d’une bibliothèque soit inclus si ce n’est pas déjà fait. Le ?chier est inclus via le mécanisme
do-FICHIER qui est pratiquement une variante de eval(). Sa sémantique est similaire à la procédure suivante :
sub require {
my($filename) = @_;
return 1 if $INC{$filename};
my($realfilename,$result);
ITER: {
foreach $prefix (@INC) {
$realfilename = "$prefix/$filename";
if (-f $realfilename) {
$INC{$filename} = $realfilename;
$result = do $realfilename;
last ITER;
}
}
die "Can’t find $filename in \@INC";
}
delete $INC{$filename} if $@ || !$result;
die $@ if $@;
die "$filename did not return true value" unless $result;
return $result;
}
Remarquez que le ?chier ne sera pas inclus deux fois sous le même nom. Le ?chier doit retourner true (vrai) par sa dernière
instruction pour indiquer un exécution correcte du code d’initialisation. Il est donc courant de terminer un tel ?chier par un
"1;" à moins d’être sûr qu’il retournera true (vrai) par un autre moyen. Mais il est plus sûr de mettre "1;" au cas où vous
ajouteriez quelques instructions.
Si EXPR est un nom simple (bareword), require suppose l’extension ".pm" et remplace pour vous les "::" par des "" dans le
nom du ?chier a?n de rendre plus simple le chargement des modules standards. Cette forme de chargement des modules ne
risque pas d’altérer votre espace de noms.
En d’autres termes, si vous dites :
require Foo::Bar;
# un splendide mot simple
La fonction require cherchera en fait le ?chier "" dans les répertoires spéci?és par le tableau @INC.
Mais si vous essayez :
$class = ’Foo::Bar’;
require $class;
# $class n’est pas un mot simple
#ou
require "Foo::Bar";
# n’est pas un mot simple à cause des guillemets
110

7.1. DESCRIPTION
perlfunc
La fonction require cherchera le ?chier "Foo::Bar" dans les répertoires du tableau @INC et se plaindra qu’elle ne peut trouver
le ?chier "Foo::Bar". Dans ce cas, vous pouvez faire :
eval "require $class";
Pour une fonctionnalité d’importation encore plus puissante, voir le titre use dans ce document et le manuel perlmod.
reset EXPR
reset
Généralement utilisée dans un bloc continue à la ?n d’une boucle pour effacer les variables et réinitialiser les recherches ??
pour qu’elle marche à nouveau. L’expression EXPR est interprétée comme une liste de caractères (le moins est autorisé pour
des intervalles). Toutes les variables commençant par l’un de ces caractères sont réinitialisées à leur état primitif. Si EXPR
est omis, les motifs de recherche qui ne marchent qu’une fois (?motif?) sont réinitialisés pour fonctionner à nouveau. Ne
réinitialise que les variables et les motifs du paquetage courant. Retourne toujours 1. Exemples :
reset ’X’;
# réinitialise toutes les variables X
reset ’a-z’;
# réinitialise toutes les variables
# commençant par une minuscule
reset;
# réinitialise juste les motifs ? ?
Réinitialiser "A-Z" n’est pas recommandé parce que cela efface les tableaux @ARGV et @INC ainsi que la table de hachage %ENV.
Ne réinitialise que les variables de paquetage – les variables lexicales ne sont pas modi?ées mais elles s’effacent toutes seules
dès que l’on sort de leur portée ce qui devrait vous inciter à les utiliser. Voir le titre my dans ce document.
return EXPR
return
Sort d’une subroutine, d’un bloc eval() ou d’un do FICHIER en retournant la valeur donnée par EXPR. L’évaluation de
EXPR peut se faire dans un contexte scalaire, de liste ou vide selon la manière dont la valeur sera utilisée. Le contexte peut
varier d’une exécution à l’autre (voir wantarray()). Si aucune EXPR n’est donnée, retourne la liste vide dans un contexte de
liste, la valeur undef dans un contexte scalaire et rien du tout dans un contexte vide.
(Remarque: en l’absence de return, une subroutine, un bloc eval ou un do FICHIER retournera automatiquement la valeur de
la dernière expression évaluée.)
reverse LISTE
Dans un contexte de liste, retourne une liste de valeurs constituée des éléments de LISTE en ordre inverse. Dans un contexte
scalaire, concatène les éléments de LISTE et retourne la chaîne ainsi constituée mais avec les caractères dans l’ordre inverse.
print reverse <>;
# tac (cat à l’envers) les lignes,
# la dernière ligne en premier
undef $/;
# pour un <> efficace
print scalar reverse <>;
# tac (cat à l’envers) les octets,
# la dernière ligne en reimerp
Cet opérateur est aussi utilisé pour inverser des tables de hachage bien que cela pose quelques problèmes. Si une valeur est
dupliquée dans la table originale, seule l’une des ces valeurs sera représentée comme une clé dans la table résultante. Cela
nécessite aussi de mettre toute la table à plat avant d’en reconstruire une nouvelle ce qui peut prendre beaucoup de temps sur
une grosse table telle qu’un ?chier DBM.
%by_name = reverse %by_address;
# Inverse la table
rewinddir DIRHANDLE
Ramène la position courante au début du répertoire pour le prochain readdir() sur DIRHANDLE.
rindex CHAINE,SUBSTR,POSITION
rindex CHAINE,SUBSTR
Fonctionne exactement comme index sauf qu’il retourne la position de la dernière occurrence de SUBSTR dans CHAINE. Si
POSITION est spéci?ée, retourne la dernière occurrence avant ou exactement à cette position.
rmdir REPNOM
rmdir
Efface le répertoire spéci?é par REPNOM si ce répertoire est vide. En cas de succès, retourne true (vrai) ou sinon, retourne
false (faux) et positionne la variable $! (errno). Si REPNOM est omis, utilise $_.
s///
L’opérateur de substitution. Voir le manuel perlop.
111

7.1. DESCRIPTION
perlfunc
scalar EXPR
Contraint l’interprétation de EXPR dans un contexte scalaire et retourne la valeur de EXPR.
@counts = ( scalar @a, scalar @b, scalar @c );
Il n’y pas d’opérateur équivalent pour contraindre l’interprétation d’une expression dans un contexte de liste parce qu’en
pratique ce n’est jamais nécessaire. Si vous en avez réellement besoin, vous pouvez utiliser une construction comme @{[
(une expression) ]} mais un simple (une expression) suf?t en général.
Comme scalar est un opérateur unaire, si vous l’utilisez accidentellement sur une EXPR constituée d’une liste entre paren-
thèses, cela se comporte comme l’opérateur scalaire virgule en évaluant tous les éléments dans un contexte vide sauf le dernier
élément qui est évalué dans un contexte scalaire et retourné. C’est rarement ce que vous vouliez.
L’instruction suivante :
print uc(scalar(&foo,$bar)),$baz;
est équivalente à ces deux instructions :
&foo;
print(uc($bar),$baz);
Voir le manuel perlop pour les détails sur les opérateurs unaires et l’opérateur virgule.
seek DESCRIPTEUR,POSITION,WHENCE
Modi?e la position d’un DESCRIPTEUR exactement comme le fait l’appel fseek() de stdio(). DESCRIPTEUR peut être
une expression dont la valeur donne le nom du descripteur. Les valeurs possibles de WHENCE sont 0 pour régler la nouvelle
position à POSITION, 1 pour la régler à la position courante plus POSITION ou 2 pour la régler à EOF plus POSITION
(en général négative). Pour WHENCE, vous pouvez utiliser les constantes SEEK_SET, SEEK_CUR et SEEK_END provenant du
module Fcntl.. Renvoie 1 en cas de succès et 0 sinon.
Si vous voulez régler la position pour un ?chier dans le but d’utiliser sysread() ou syswrite(), n’utilisez pas seek() – la
bufferisation rend ses effets imprévisibles et non portables. Utilisez sysseek() à la place.
À cause des règles et de la rigueur du C ANSI, sur certains systèmes, vous devez faire un seek à chaque fois que vous basculer
entre lecture et écriture. Entre autres choses, cela a pour effet d’appeler la fonction clearerr(3) de stdio. Un WHENCE de 1
(SEEK_CUR) est pratique pour ne pas modi?er la position dans le ?chier :
seek(TEST,0,1);
C’est aussi très pratique pour les applications qui veulent simuler tail -f. Une fois rencontré un EOF en lecture et après avoir
attendu un petit peu, vous devez utiliser seek() pour réactiver les choses. L’appel à seek() ne modi?e pas la position courante
mais par contre, il efface la condition ?n-de-?chier (EOF) sur le descripteur et donc, au prochain <FILE>, Perl essayera à
nouveau de lire quelque chose. Espérons-le.
Si cela ne marche pas (certaines bibliothèques stdio sont particulièrement hargneuses) alors vous devrez faire quelque chose
comme :
for (;;) {
for ($curpos = tell(FILE); $_ = <FILE>;
$curpos = tell(FILE)) {
# search for some stuff and put it into files
}
sleep($for_a_while);
seek(FILE, $curpos, 0);
}
seekdir DIRHANDLE,POS
Règle la position courante pour la routine readdir() sur un DIRHANDLE. POS doit être une valeur retournée par telldir().
Possède les même limitations que l’appel système correspondant.
select DESCRIPTEUR
select
Retourne le descripteur courant. Sélectionne le descripteur DESCRIPTEUR comme sortie par défaut si DESCRIPTEUR
est fourni. Ceci a deux effets : tout d’abord, un write() ou un print() sans descripteur spéci?é iront par défaut sur ce
DESCRIPTEUR. Ensuite, toutes références à des variables relatives aux sorties se référeront à ce canal de sortie. Par exemple,
si vous devez spéci?er un en-tête de format pour plusieurs canaux de sortie, vous devez faire la chose suivante :
112

7.1. DESCRIPTION
perlfunc
select(REPORT1);
$^ = ’report1_top’;
select(REPORT2);
$^ = ’report2_top’;
DESCRIPTEUR peut être une expression dont le résultat donne le nom du descripteur réel. Donc :
$oldfh = select(STDERR); $| = 1; select($oldfh);
Certains programmeurs préfèrent considérer les descripteurs comme des objets avec des méthodes. Ils écriraient donc
l’exemple précédent de la manière suivante :
use IO::Handle;
STDERR->autoflush(1);
select RBITS,WBITS,EBITS,TIMEOUT
Ceci utilise directement l’appel système select(2) avec les masques de bit spéci?és qui peuvent être construits en utilisant
fileno() et vec() comme dans les lignes suivantes :
$rin = $win = $ein = ’’;
vec($rin,fileno(STDIN),1) = 1;
vec($win,fileno(STDOUT),1) = 1;
$ein = $rin | $win;
Si vous voulez surveiller de nombreux descripteurs, vous aurez peut-être à écrire une subroutine :
sub fhbits {
my(@fhlist) = split(’ ’,$_[0]);
my($bits);
for (@fhlist) {
vec($bits,fileno($_),1) = 1;
}
$bits;
}
$rin = fhbits(’STDIN TTY SOCK’);
L’appel classique est :
($nfound,$timeleft) =
select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
ou pour attendre que quelque chose soit prêt :
$nfound = select($rout=$rin, $wout=$win, $eout=$ein, undef);
De nombreux systèmes ne prennent pas la peine de retourner quelque chose d’utile dans $timeleft (le temps restant). En
conséquence, un appel à select() dans un contexte scalaire retourne juste $nfound.
undef est une valeur acceptable pour les masques de bits. Le timeout, si il est spéci?ée, est donné en secondes et peut être
fractionnaire. Note : certaines implémentations ne sont pas capables de retourner $timeleft. Dans ce cas, elles retournent
toujours un $timeleft égal au $timeout fourni.
Vous pouvez spéci?er une attente de 250 millisecondes de la manière suivante :
select(undef, undef, undef, 0.25);
ATTENTION : il ne faut pas mélanger des E/S bufferisées (comme read() ou <FH>) avec select() excepté lorsque la
norme POSIX le permet et, dans ce cas, uniquement sur les systèmes POSIX. Vous devez utiliser sysread() à la place.
semctl ID,SEMNUM,CMD,ARG
Appelle la fonction semctl() des IPC System V. Vous aurez sans doute besoin de :
use IPC::SysV;
au préalable pour avoir les dé?nitions correctes des constantes. Si CMD est IPC_STAT ou GETALL alors ARG doit être une
variable capable de contenir la structure semid_ds retournée ou le tableau des valeurs des sémaphores. Les valeurs retournées
sont comme celles de ioctl() : la valeur undef en cas d’erreur, la chaîne "0 but true" pour rien ou la vraie valeur retournée
dans les autres cas. ARG doit être un vecteur d’entiers courts (short) natifs qui peut être créé par pack("s!",(0)x$nsem).
Voir aussi la documentation de IPC::SysV et de IPC::SysV::Semaphore.
113

7.1. DESCRIPTION
perlfunc
semget KEY,NSEMS,FLAGS
Appelle la fonction semget() des IPC System V. Renvoie l’id du sémaphore ou la valeur undef en cas d’erreur. Voir aussi la
documentation de IPC::SysV et de IPC::SysV::Semaphore.
semop KEY,OPSTRING
Appelle la fonction semop() des IPC System V pour réaliser certaines opérations sur les sémaphores comme l’attente ou la
signalisation. OPSTRING doit être un tableau compacté (par pack()) de structures semop. Chaque structure semop peut être
générée par pack("sss", $semnum, $semop, $semflag). Le nombre total d’opérations sur les sémaphores est déduit de la
taille de OPSTRING. Renvoie true (vrai) en cas de succès ou false (faux) en cas d’erreur. Par exemple, le code suivant attend
sur le sémaphore $semnum de l’ensemble de sémaphores d’id $semid :
$semop = pack("sss", $semnum, -1, 0);
die "Semaphore trouble: $!\n" unless semop($semid, $semop);
Pour envoyer un signal au sémaphore, remplacez le -1 par 1. Voir aussi la documentation de IPC::SysV et de
IPC::SysV::Semaphore.
send SOCKET,MSG,FLAGS,TO
send SOCKET,MSG,FLAGS
Envoie un message sur un socket. Utilise les mêmes ?ags que l’appel système du même nom. Pour des sockets non-connectés
vous devez spéci?er dans le paramètre TO une destination pour l’envoi. Dans ce cas c’est la fonction C sendto() qui est
utilisée. Retourne le nombre de caractères envoyés ou la valeur undef si il y a une erreur. L’appel système sendmsg(2) n’est
pas implémenté pour l’instant. Voir les exemples dans le titre UDP : Transfert de Message dans le manuel perlipc.
setpgrp PID,PGRP
Modi?e le groupe de process courant pour le PID spéci?é (0 pour le process courant). Cela produira une erreur fatale si vous
l’utilisez sur un système qui n’implémente pas l’appel POSIX setpgid(2) ou l’appel BSD setpgrp(2). Si les arguments sont
omis, ils prennent comme valeur par défaut 0,0. Remarquez aussi que la version BSD 4.2 de setpgrp() n’accepte aucun
argument. Donc seul setpgrp 0,0 est portable. Voir aussi POSIX::setsid().
setpriority WHICH,WHO,PRIORITY
Modi?e la priorité courante d’un process, d’un groupe de process ou d’un utilisateur. (Voir setpriority(2).) Cela produira une
erreur fatale si vous l’utilisez sur un système qui n’implémente pas setpriority(2).
setsockopt SOCKET,LEVEL,OPTNAME,OPTVAL
Modi?e l’option spéci?ée d’un socket. Retourne undef en cas d’erreur. OPTVAL peut être undef si vous ne voulez pas passer
d’argument.
shift TABLEAU
shift
Retourne la première valeur d’un tableau après l’avoir supprimer du tableau en rétrécissant sa taille de 1 et en déplaçant tout
vers le bas. Renvoie undef si il n’y a pas d’éléments dans le tableau. Si TABLEAU est omis, shift agira soit sur le tableau @_
si il est dans la portée lexicale d’une subroutine ou d’un format, soit sur le tableau @ARGV si il est dans la portée lexicale d’un
?chier ou si il est dans une portée lexicale établie par l’une des constructions eval ”, BEGIN {}, END {} ou INIT {}.
Voir aussi unshift, push et pop. shift() et unshift() agissent sur le côté gauche d’un tableau exactement comme pop()
et push() le font sur le côté droit.
shmctl ID,CMD,ARG
Appelle la fonction shmctl de IPC System V. Vous aurez sans doute besoin de :
use IPC::SysV;
au préalable pour avoir les dé?nitions correctes des constantes. Si CMD est IPC_STAT alors ARG doit être une variable capable
de contenir la structure shmid_ds retournée. Les valeurs retournées sont comme celles de ioctl() : la valeur undef en cas
d’erreur, la chaîne "0 but true" pour zéro ou la vraie valeur retournée dans les autres cas. Voir aussi la documentation de
IPC::SysV.
shmget KEY,SIZE,FLAGS
Appelle la fonction shmget de IPC System V. Renvoie l’id du segment de mémoire partagée ou undef en cas d’erreur. Voir
aussi la documentation de IPC::SysV.
shmread ID,VAR,POS,SIZE
shmwrite ID,CHAINE,POS,SIZE
Lit ou écrit le segment de mémoire partagée System V d’id ID en commençant à la position POS et sur une taille de SIZE en
s’attachant à lui puis en le lisant ou en l’écrivant puis en?n en s’en détachant. Lors d’une lecture, VAR doit être une variable
qui contiendra les données lues. Lors d’une écriture, si CHAINE est trop long, seuls SIZE octets seront utilisés, si CHAINE
est trop court des caractères nuls seront ajoutés pour compléter jusqu’à SIZE octets. Retourne true (vrai) en cas de succès et
false (faux) en cas d’erreur. shmread() souille (taint) la variable CHAINE. Voir aussi la documentation de IPC::SysV.
114

7.1. DESCRIPTION
perlfunc
shutdown SOCKET,HOW
Ferme une connexion socket de la manière indiquée par HOW qui est interprété comme le fait l’appel système du même nom.
shutdown(SOCKET, 0);
# J’ai arrêté de lire des données
shutdown(SOCKET, 1);
# J’ai arrêté d’écrire des données
shutdown(SOCKET, 2);
# J’ai arrêté d’utiliser ce socket
C’est pratique pour des sockets pour lesquels vous voulez indiquer à l’autre extrémité que vous avez ?ni d’écrire mais pas de
lire ou vice versa. C’est aussi une forme plus insistante de close puisque qu’elle désactive aussi le descripteur de ?chier pour
tous les process dupliqués par fork.
sin EXPR
sin
Retourne le sinus de EXPR (exprimé en radians). Si EXPR est omis, retourne le sinus de $_.
Pour calculer la fonction inverse du sinus, vous pouvez utiliser la fonction Math::Trig::asin ou utiliser cette relation :
sub asin { atan2($_[0], sqrt(1 - $_[0] * $_[0])) }
sleep EXPR
sleep
Demande au script de s’endormir pendant EXPR secondes ou pour toujours si EXPR est omis. Peut être interrompu si le
process reçoit un signal comme SIGALRM. Renvoie le durée réelle du sommeil en secondes. Vous ne pourrez probablement pas
mélanger des appels alarm() et sleep() car sleep() est souvent implémenté en utilisant alarm().
Sur quelques vieux systèmes, il se peut que la durée du sommeil soit d’une seconde de moins que celle que vous avez demandée
en fonction de la manière dont il compte les secondes. Les systèmes plus modernes s’endorment toujours pendant la bonne
durée. En revanche, il peut arriver que votre sommeil dure plus longtemps que prévu sur un système multi-tâches très chargé.
Pour des délais d’une granularité inférieure à la seconde, vous pouvez utiliser l’interface Perl syscall() pour accéder à
setitimer(2) si votre système le supporte ou sinon regarder le titre select() dans ce document plus haut. Le module Time::HiRes
disponible sur CPAN peut aussi aider.
Regarder aussi la fonction sigpause() du module POSIX.
socket SOCKET,DOMAIN,TYPE,PROTOCOL
Ouvre un socket du type spéci?é et l’attache au descripteur SOCKET. DOMAIN, TYPE et PROTOCOL sont spéci?és comme
pour l’appel système du même nom. Vous devriez mettre "use Socket;" au préalable pour importer les dé?nitions correctes.
Voir les exemple dans le titre Sockets : Communication Client/Serveur dans le manuel perlipc.
Sur les systèmes qui supportent le drapeau fermeture-à-l-exécution (close-on-exec) sur les ?chiers, ce drapeau sera positionné
pour de nouveaux descripteurs de ?chier en fonction de la valeur de $ˆF. Voir le titre $ˆF dans le manuel perlvar.
socketpair SOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL
Crée une paire de sockets sans nom dans le domaine spéci?é et du type spéci?é. DOMAIN, TYPE et PROTOCOL sont
spéci?és comme pour l’appel système du même nom. Si l’appel système n’est pas implémenté, cela produit une erreur fatale.
Retourne true (vrai) en cas de succès.
Sur les systèmes qui supportent le drapeau fermeture-à-l-exécution (close-on-exec) sur les ?chiers, ce drapeau sera positionné
pour de nouveaux descripteurs de ?chier en fonction de la valeur de $ˆF. Voir le titre $ˆF dans le manuel perlvar.
Certains systèmes dé?nissent pipe() en terme de socketpair(), auquel cas un appel à pipe(Rdr, Wtr) est quasiment
équivalent à :
use Socket;
socketpair(Rdr, Wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
shutdown(Rdr, 1);
# plus d’écriture pour le lecteur
shutdown(Wtr, 0);
# plus de lecture pour l’écrivain
Voir le manuel perlipc pour des exemples d’utilisation de socketpair.
sort SUBNAME LISTE
sort BLOC LISTE
sort LISTE
Trie LISTE et retourne la liste de valeurs triée. Si SUBNAME et BLOC sont omis, le tri est effectué dans l’ordre standard
de comparaison de chaînes. Si SUBNAME est spéci?é, il donne le nom d’une subroutine qui retourne un entier plus petit,
égale ou plus grand que 0 selon l’ordre dans lequel les éléments du tableau doivent être triés. (Les opérateurs <=> et cmp sont
extrêmement utiles dans de telles subroutines.) SUBNAME peut être une variable scalaire auquel cas sa valeur donne le nom
(ou la référence) de la subroutine à utiliser. À la place de SUBNAME, vous pouvez fournir un BLOC comme subroutine de tri
anonyme et en ligne.
115

7.1. DESCRIPTION
perlfunc
Si le prototype de la subroutine est ($$), les éléments à comparer sont passés par référence dans @_ comme pour une subroutine
normale. C’est plus lent qu’une subroutine sans prototype pour laquelle les éléments à comparer sont passés à la subroutine
par les variables globales du package courant $a et $b (voir exemples ci-dessous). Dans ce dernier cas, il est contre-productif
de déclarer $a et $b comme des variables lexicales.
Dans tous les cas, la subroutine ne peut pas être récursive. Les valeurs à comparer sont toujours passées par référence. Donc,
ne les modi?ez pas.
Vous ne pouvez pas non plus sortir du bloc sort ou de la subroutine en utilisant un goto() ou les opérateurs de contrôle de
boucles décrits dans le manuel perlsyn.
Lorsque use locale est actif, sort LISTE trie LISTE selon l’ordre (collation) du locale courant. Voir le manuel perllocale.
Exemples :
# tri alphabétique
@articles = sort @files;
# idem mais avec une routine de tri explicite
@articles = sort {$a cmp $b} @files;
# idem mais indépendant de la casse
@articles = sort {uc($a) cmp uc($b)} @files;
# idem mais dans l’ordre inverse
@articles = sort {$b cmp $a} @files;
# tri numérique ascendant
@articles = sort {$a <=> $b} @files;
# tri numérique descendant
@articles = sort {$b <=> $a} @files;
# tri de %age par valeur plutôt que par clé
# en utilisant une fonction en-ligne
@eldest = sort { $age{$b} <=> $age{$a} } keys %age;
# tri utilisant le nom explicite d’une subroutine
sub byage {
$age{$a} <=> $age{$b};
# supposé numérique
}
@sortedclass = sort byage @class;
sub backwards { $b cmp $a; }
@harry
= qw(dog cat x Cain Abel);
@george = qw(gone chased yz Punished Axed);
print sort @harry;
# affiche AbelCaincatdogx
print sort backwards @harry;
# affiche xdogcatCainAbel
print sort @george, ’to’, @harry;
# affiche AbelAxedCainPunishedcatchaseddoggonetoxyz
# tri inefficace par ordre numérique descendant utilisant
# le premier entier après le signe = ou l’ensemble de
# l’enregistrement si cet entier n’existe pas
@new = sort {
($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0]
||
uc($a)
cmp
uc($b)
} @old;
# la même chose mais plus efficace;
# nous construisons un tableau auxilliaire d’indices
# pour aller plus vite
@nums = @caps = ();
for (@old) {
push @nums, /=(\d+)/;
push @caps, uc($_);
}
116

7.1. DESCRIPTION
perlfunc
@new = @old[ sort {
$nums[$b] <=> $nums[$a]
||
$caps[$a] cmp $caps[$b]
} 0..$#old
];
# même chose sans utiliser de variables temporaires
@new = map { $_->[0] }
sort { $b->[1] <=> $a->[1]
||
$a->[2] cmp $b->[2]
} map { [$_, /=(\d+)/, uc($_)] } @old;
# l’utilisation d’un prototype vous permet d’utiliser
# n’importe quelle subroutine de comparaison comme
# subroutine de tri (y compris des subroutines d’autres packages)
package other;
sub backwards ($$) { $_[1] cmp $_[0]; }
# $a and $b are not set here
package main;
@new = sort other::backwards @old;
Si vous utilisez strict, vous NE DEVEZ PAS déclarer $a et $b comme variables lexicales. Ce sont des variables globales au
package. Cela signi?e que si vous êtes dans le package main, c’est :
@articles = sort {$main::b <=> $main::a} @files;
ou juste :
@articles = sort {$::b <=> $::a} @files;
mais si vous êtes dans le package FooPack, <c’est :>
@articles = sort {$FooPack::b <=> $FooPack::a} @files;
La fonction de comparaison doit se comporter correctement. Si elle retourne des résultats incohérents (parfois elle dit que
$x[1] est plus petit que $x[2] et d’autres fois le contraire par exemple), le résultat du tri n’est pas bien dé?ni.
splice TABLEAU,OFFSET,LONGUEUR,LISTE
splice TABLEAU,OFFSET,LONGUEUR
splice TABLEAU,OFFSET
splice TABLEAU
Supprime d’un tableau les éléments consécutifs désignés par OFFSET (indice du premier élément) et LONGUEUR (nombre
d’éléments concernés) et les remplace par les éléments de LISTE si il y en a. Dans un contexte de liste, renvoie les élé-
ments supprimés du tableau. Dans un contexte scalaire, renvoie le dernier élément supprimé ou undef si aucun élément n’est
supprimé. Le tableau grossit ou diminue si nécessaire. Si OFFSET est négatif, il est compté à partir de la ?n du tableau. Si
LONGUEUR est omis, supprime tout à partir de OFFSET. Si LONGUEUR est négatif, laisse ce nombre d’éléments à la ?n
du tableau. Si OFFSET et LONGUEUR sont omis, supprime tout ce qui est dans le tableau.
Les équivalences suivantes sont vraies en supposant que $[ == 0 :
push(@a,$x,$y)
splice(@a,@a,0,$x,$y)
pop(@a)
splice(@a,-1)
shift(@a)
splice(@a,0,1)
unshift(@a,$x,$y)
splice(@a,0,0,$x,$y)
$a[$x] = $y
splice(@a,$x,1,$y)
Exemple, en supposant que la longueurs des tableaux est passée avant chaque tableau :
sub aeq {
# compare deux listes de valeurs
my(@a) = splice(@_,0,shift);
my(@b) = splice(@_,0,shift);
return 0 unless @a == @b;
# même longueur ?
while (@a) {
return 0 if pop(@a) ne pop(@b);
117

7.1. DESCRIPTION
perlfunc
}
return 1;
}
if (&aeq($len,@foo[1..$len],0+@bar,@bar)) {   }
split /MOTIF/,EXPR,LIMITE
split /MOTIF/,EXPR
split /MOTIF/
split
Découpe une chaîne en une liste de chaînes et la retourne. Par défaut, les champs vides du début sont conservés et ceux de la
?n sont éliminés.
Si l’appel n’est pas dans un contexte de liste, split retourne le nombre de champs trouvés et les place dans le tableau @_. (Dans
un contexte de liste, vous pouvez forcer l’utilisation du tableau @_ en utilisant ?? comme motif délimiteur mais il renvoie
encore la liste des valeurs.) En revanche, l’utilisation implicite de @_ par split est désapprouvée parce que cela écrase les
arguments de votre subroutine.
SI EXPR est omis, split découpe la chaîne $_. Si MOTIF est aussi omis, il découpe selon les blancs (après avoir sauté d’éven-
tuels blancs au départ). Tout ce qui reconnu par MOTIF est considéré comme étant un délimiteur de champs. (Remarquez que
le délimiteur peut être plus long qu’un seul caractère.)
SI LIMITE est spéci?é et positif, ?xe le nombre maximum de champs du découpage (il est possible que le nombre de champs
soit inférieur). Si LIMITE n’est pas spéci?é ou vaut zéro, les champs vides de la ?n sont supprimés (chose dont les utilisateurs
potentiels de pop() devraient se souvenir). Si LIMITE est négatif, il est traité comme si LIMITE avait une valeur arbitrairement
très grande.
Un motif qui peut correspondre à la chaîne vide (ne pas confondre avec le motif vide // qui n’est qu’un motif parmi tous ceux
qui peuvent correspondre à la chaîne vide) découpera la valeur de EXPR en caractère séparé à chaque point où il sera reconnu.
Par exemple :
print join(’:’, split(/ */, ’hi there’));
produira la sortie ’h:i:t:h:e:r:e’.
La paramètre LIMITE peut être utilisé pour découper partiellement une ligne :
($login, $passwd, $remainder) = split(/:/, $_, 3);
Lors de l’affectation à une liste, si LIMITE est omis, Perl agit comme si LIMITE était égal au nombre de variables de la liste
plus un pour éviter tout travail inutile. Pour la liste ci-dessous, la valeur par défaut de LIMITE serait 4. Dans les applications
où le temps est critique, il vous incombe de ne pas découper en plus de champs que ceux réellement nécessaires.
Si MOTIF contient des parenthèses (et donc des sous-motifs), un élément supplémentaire est créé dans le tableau résultat pour
chaque chaîne reconnue par le sous-motif.
split(/([,-])/, "1-10,20", 3);
produit la liste de valeurs
(1, ’-’, 10, ’,’, 20)
Si vous avez dans la variable $header tout l’en-tête d’un email normal d’UNIX, vous devriez pouvoir le découper en champs
et valeurs en procédant comme suit :
$header =~ s/\n\s+/ /g;
# fix continuation lines
%hdrs
=
(UNIX_FROM => split /^(\S*?):\s*/m, $header);
Le motif /MOTIF/ peut être remplacé par une expression pour spéci?er un motif qui varie à chaque passage. (Pour faire une
compilation une seule fois lors de l’exécution, utilisez /$variable/o.)
Un cas spécial : spéci?er un blanc (’ ’) comme MOTIF découpe selon les espaces exactement comme le fait split() sans
argument. Donc, split(’ ’) peut être utilisé pour émuler le comportement par défaut de awk alors que split(/ /) vous
donnera autant de champs vides que d’espaces au début. Un split() avec /\s+/ est comme split(’ ’) sauf dans le cas de
blancs au début qui produiront un premier champ vide. Un split() sans argument effectue réellement un split(’ ’, $_)
en interne.
Exemple :
open(PASSWD, ’/etc/passwd’);
while (<PASSWD>) {
($login, $passwd, $uid, $gid,
$gcos, $home, $shell) = split(/:/);
#
}
118

7.1. DESCRIPTION
perlfunc
(Remarquez que $shell contiendra encore un caractère de passage à la ligne (newline). Voir le titre chop dans ce document,
le titre chomp dans ce document et le titre join dans ce document.)
sprintf FORMAT, LISTE
Retourne une chaîne formatée selon les conventions usuelles de la fonction sprintf() de la bibliothèque C. Voir le manuel
sprintf (3) ou le manuel printf (3) sur votre système pour une explication sur les principes généraux.
Perl a sa propre implémentation de sprintf() – elle émule la fonction C sprintf() mais elle ne l’utilise pas (sauf pour
les nombres en virgule ?ottante et encore en n’autorisant que les modi?cateurs standards). Conséquence : une extension non
standard de votre version locale de sprintf() ne sera pas disponible en Perl.
Le sprintf() de Perl autorise les conversions universellement connues :
%%
un signe pourcent
%c
un caractère dont on fournit le code
%s
une chaîne
%d
un entier signé, en décimal
%u
un entier non-signé, en décimal
%o
un entier non-signé, en octal
%x
un entier non-signé, en hexadécimal
%e
un nombre en virgule flottante, en notation scientifique
%f
un nombre en virgule flottante, avec un nombre de décimales fixe
%g
un nombre en virgule flottante, %e ou %f (au mieux)
De plus, Perl autorise les conversions largement supportées :
%X
comme %x mais avec des lettres majuscules
%E
comme %e, mais en utilisant un "E" majuscule
%G
comme %g, mais en utilisant un "E" majuscule (si nécessaire)
%b
un entier non signé, en binaire
%p
un pointeur (affiche la valeur Perl de l’adresse en hexadécimal)
%n
spécial: stocke le nombre de caractères produits dans la
prochaine variable de la liste des paramètres
Et ?nalement, pour des raisons de compatibilité (et "uniquement" pour cela), Perl autorise les conversions inutiles mais large-
ment supportées :
%i
un synonyme de %d
%D
un synonyme de %ld
%U
un synonyme de %lu
%O
un synonyme de %lo
%F
un synonyme de %f
Perl accepte les ?ags universellement connus suivants entre le % et la lettre de conversion :
espace
précède les nombres positifs par un espace
+
précède les nombres positifs par un signe plus
-
justifie le champ à gauche
0
utilise des zéros à la place des espaces pour justifier à droite
#
précède le nombre non nul en octal par "0",
précède le nombre non nul en hexadécimal par "0x"
nombre
taille minimum du champ
.nombre
"précision": nombre de décimales pour un
nombre en virgule
flottante, longueur maximum pour une chaîne, longueur minimum
pour un entier
l
interprète un entier comme le type C "long" ou "unsigned long"
h
interprète un entier comme le type C "short" ou "unsigned short"
Il y a aussi deux ?ags spéci?ques à Perl :
V
interprète un entier comme le type entier standard de Perl
v
interprète la chaîne comme un vecteur d’entiers. Affichera
ces entiers séparés par des points ou par une chaîne arbitraire
reçue dans la liste des arguments si le flag est précédé
de C<*>
119

7.1. DESCRIPTION
perlfunc
À chaque fois qu’un nombre peut être spéci?é comme ?ag, on peut le remplacer par un astérisque ("*") auquel cas Perl utilise
le prochain item de la liste des paramètres comme valeur pour ce nombre (c’est à dire comme longueur ou précision du champ).
Si un champ de longueur obtenu par "*" est négatif alors cela a le même effet que le ?ag "-" : justi?cation à gauche.
Le ?ag v est pratique pour af?cher les valeurs représentées par des caractères dans une chaîne arbitraire :
printf "version is v%vd\n", $^V;
# version de Perl
printf "address is %*vX\n", ":", $addr;
# adresse IPv6
printf "bits are %*vb\n", " ", $bits;
# chaîne de bits aléatoire
Si use locale est actif, le caractère utilisé comme séparateur décimal pour les nombres réels dépend de la valeur de
LC_NUMERIC. Voir le manuel perllocale.
Si Perl comprend les "quads" (les entiers sur 64-bit) (cela nécessite soit que la plate-forme native supporte les quads soit que
Perl a été compilé spéci?quement pour supporté les quads), les caractères :
d u o x X b i D U O
af?che des quads et ils peuvent être précédé par :
ll L q
Par exemple :
%lld %16LX %qo
Vous pouvez savoir si Perl supporte les long doubles via le manuel Con?g :
use Config;
$Config{d_longdbl} eq ’define’ && print "long doubles\n";
sqrt EXPR
sqrt
Renvoie la racine carrée de EXPR. Si EXPR est omis, retourne la racine carrée de $_. Ne fonctionne que sur les opérandes
non négatifs à moins que vous n’ayez chargé le module standard Math::Complex.
use Math::Complex;
print sqrt(-2);
# affiche 1.4142135623731i
srand EXPR
srand
Fixe la graine aléatoire pour l’opérateur rand(). Si EXPR est omis, on utilise une valeur pseudo-aléatoire fournie par le noyau
(si il supporte le device /dev/urandom) ou basée entre autres sur l’heure courante et l’ID du process. Dans les versions de
Perl antérieures à la version 5.004, la valeur par défaut était juste time(). Ce n’est pas une graine particulièrement bonne
et donc de nombreux programmes anciens fournissaient leur propre valeur de graine (souvent time ˆ $$ ou time ˆ ($$ +
($$ << 15))) mais ce n’est plus nécessaire maintenant.
En fait, il n’est même plus nécessaire d’appeler srand() puisque s’il n’est pas appelé explicitement, il l’est implicitement
lors de la première utilisation de l’opérateur rand(). Par contre, ce n’était pas le cas dans les versions de Perl antérieures à la
version 5.004 et donc, si votre script doit pouvoir tourner avec de vieilles versions de Perl, il doit appeler srand().
Remarque: vous devez utiliser quelque chose de beaucoup plus aléatoire que la graine par défaut pour des applications de cryp-
tographie. Le checksum d’une sortie compressée d’un ou plusieurs programmes système dont les valeurs changent rapidement
est une méthode usuelle. Par exemple :
srand (time ^ $$ ^ unpack "%L*", ‘ps axww | gzip‘);
Si cela vous intéresse tout particulièrement, regardez le module CPAN Math::TrulyRandom.
N’appelez pas srand() plusieurs fois dans votre programme à moins de savoir exactement ce que vous faites et pourquoi vous
le faites. L’objectif de cette fonction est d’initialiser la fonction rand() a?n qu’elle produise une séquence différente à chaque
exécution de votre programme. Faites le une bonne fois pour toutes au début de votre programme ou rand() ne vous produira
pas des nombres aléatoires.
Les programmes fréquemment utilisés (comme des scripts CGI) qui utilisent simplement :
time ^ $$
comme graine peuvent tomber sur la propriété mathématique suivante :
a^b == (a+1)^(b+1)
120

7.1. DESCRIPTION
perlfunc
une fois sur trois. Donc ne faites pas ça.
stat DESCRIPTEUR
stat EXPR
stat
Retourne une liste de 13 éléments donnant des informations sur l’état soit du ?chier dont le nom est donné par EXPR soit
du ?chier ouvert par DESCRIPTEUR. Si EXPR est omis, retourne l’état de $_. Retourne une liste vide en cas d’échec.
Typiquement utilisé de la manière suivante :
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks)
= stat($filename);
Certains champs ne sont pas gérés par certains types de systèmes de ?chiers. Voici la signi?cation de ces champs :
0 dev
numéro de device du système de fichiers
1 ino
numéro d’inode
2 mode
droits du fichier
(type et permissions)
3 nlink
nombre de liens (hard) sur le fichier
4 uid
ID numérique de l’utilisateur propriétaire du fichier
5 gid
ID numérique du groupe propriétaire du fichier
6 rdev
l’identificateur de device (fichiers spéciaux uniquement)
7 size
taille totale du fichier, en octets
8 atime
date de dernier accès en secondes depuis l’origine des temps
9 mtime
date de dernière modification en secondes
depuis l’origine des temps
10 ctime
date de dernière modification de l’inode (pas la date de
création) en secondes depuis l’origine des temps
11 blksize
taille de blocs préférée pour les E/S sur fichiers
12 blocks
nombre de blocs réellement occupés
(Sur la plupart des systèmes, l’origine des temps est ?xé au 1er janvier 1970 à minuit GMT.)
Si vous passez à stat le descripteur spécial dont le nom est le caractère souligné seul, aucun appel à stat n’est effectué par
contre le contenu courant de la structure d’état du dernier appel à stat ou du dernier test de ?chier est retourné. Exemple :
if (-x $file && (($d) = stat(_)) && $d < 0) {
print "$file is executable NFS file\n";
}
(Ceci ne marche que sur les machines dont le numéro de device est négatif sous NFS.)
Comme le mode contient à la fois le type de ?chier et les droits d’accès, vous devrez masquer la portion concernant le type de
?chier et utiliser (s)printf avec le format "%o" pour voir les véritables permissions :
$mode = (stat($filename))[2];
printf "Permissions are %04o\n", $mode & 07777;
Dans un contexte scalaire, stat() retourne une valeur booléenne indiquant le succès ou l’échec et positionne, en cas de succès,
les informations lié au descripteur spécial _.
Le module File::stat fournit un mécanisme pratique d’accès par nom :
use File::stat;
$sb = stat($filename);
printf "File is %s, size is %s, perm %04o, mtime %s\n",
$filename, $sb->size, $sb->mode & 07777,
scalar localtime $sb->mtime;
Vous pouvez importer les constantes symboliques de permissions (S_IF*) et les fonctions de test (S_IS*) depuis le module
Fcntl :
use Fcntl ’:mode’;
$mode = (stat($filename))[2];
$user_rwx
= ($mode & S_IRWXU) >> 6;
$group_read
= ($mode & S_IRGRP) >> 3;
$other_execute =
$mode & S_IXOTH;
121

7.1. DESCRIPTION
perlfunc
printf "Permissions are %04o\n", S_ISMODE($mode), "\n";
$is_setuid
=
$mode & S_ISUID;
$is_setgid
=
S_ISDIR($mode);
Vous pourriez écrire ces deux derniers exemples en utilisant les opérateurs -u et -d. Les constantes communes disponibles
sont :
# Droits : lecture, écriture, exécution,
# pour utilisateur, groupe, autres.
S_IRWXU S_IRUSR S_IWUSR S_IXUSR
S_IRWXG S_IRGRP S_IWGRP S_IXGRP
S_IRWXO S_IROTH S_IWOTH S_IXOTH
# Setuid/Setgid/Stickiness.
S_ISUID S_ISGID S_ISVTX S_ISTXT
# File types.
Not necessarily all are available on your system.
S_IFREG S_IFDIR S_IFLNK S_IFBLK S_ISCHR S_IFIFO S_IFSOCK S_IFWHT S_ENFMT
# The following are compatibility aliases for S_IRUSR, S_IWUSR, S_IXUSR.
S_IREAD S_IWRITE S_IEXEC
et les fonctions S_IF* <sont :>
S_IFMODE($mode)
the part of $mode containg the permission bits
and the setuid/setgid/sticky bits
S_IFMT($mode)
the part of $mode containing the file type
which can be bit-anded with e.g. S_IFREG
or with the following functions
# The operators -f, -d, -l, -b, -c, -p, and -s.
S_ISREG($mode) S_ISDIR($mode) S_ISLNK($mode)
S_ISBLK($mode) S_ISCHR($mode) S_ISFIFO($mode) S_ISSOCK($mode)
# No direct -X operator counterpart, but for the first one
# the -g operator is often equivalent.
The ENFMT stands for
# record flocking enforcement, a platform-dependent feature.
S_ISENFMT($mode) S_ISWHT($mode)
Voir la documentation native de chmod(2) et de stat(2) pour de meilleures informations au sujet des constantes S_*.
study SCALAIRE
study
Prend du temps supplémentaire pour étudier (study) la chaîne SCALAIRE (ou $_ si SCALAIRE est omis) a?n d’anticiper
de nombreuses recherches d’expressions rationnelles sur elle avant sa prochaine modi?cation. Cela peut améliorer ou non
le temps de recherche selon la nature et le nombre de motifs que vous recherchez et selon la fréquence de distribution des
caractères dans la chaîne – vous devriez probablement comparer les temps d’exécution avec et sans pour savoir quand cela est
plus rapide. Les boucles qui recherchent de nombreuses petites chaînes constantes (même celles comprises dans des motifs
plus complexes) en béné?cient le plus. Il ne peut y avoir qu’un seul study() actif à la fois – si vous étudiez un autre scalaire,
le précédent est "oublié". (study() fonctionne de la manière suivante : on construit une liste chaînée de tous les caractères de
la chaîne à étudier ce qui permet de savoir, par exemple, où se trouve tous les ’k’. Dans chaque chaîne recherchée, on choisit
le caractère le plus rare en se basant sur une table de fréquences construite à partir de programmes C et de textes anglais. Seuls
sont examinés les endroits qui contiennent ce caractère "rare".)
Par exemple: voici la boucle qui insère une entrée d’index devant chaque ligne contenant un certain motif :
while (<>) {
study;
print ".IX foo\n" if /\bfoo\b/;
print ".IX bar\n" if /\bbar\b/;
print ".IX blurfl\n" if /\bblurfl\b/;

print;
}
122

7.1. DESCRIPTION
perlfunc
Lors de la recherche de /\bfoo\b/, seuls sont examinés les endroits de $_ contenant f parce que f est plus rare que o. En
général, le gain est important sauf dans des cas pathologiques. Savoir si l’étude initiale est moins coûteuse que le temps gagné
lors de la recherche est la seule vraie question.
Remarquez que si vous faîtes une recherche sur des chaînes que vous ne connaissez que lors de l’exécution, vous pouvez alors
construire une boucle entière dans une chaîne que vous évaluerez via eval() a?n d’éviter de recompiler vos motifs à chaque
passage. Combiné avec l’affectation de undef à $/ pour lire chaque ?chier comme un seul enregistrement, cela peut être
extrêmement rapide et parfois même plus rapide que des programmes spécialisés comme fgrep(1). Le code suivant recherche
une liste de mots (@words) dans une liste de ?chiers (@files) et af?che la liste des ?chiers qui contiennent ces mots :
$search = ’while (<>) { study;’;
foreach $word (@words) {
$search .= "++\$seen{\$ARGV} if /\\b$word\\b/;\n";
}
$search .= "}";
@ARGV = @files;
undef $/;
eval $search;
# ca parle
$/ = "\n";
# retour au délimiteur de ligne normal
foreach $file (sort keys(%seen)) {
print $file, "\n";
}
sub BLOC
sub NOM
sub NOM BLOC
C’est la dé?nition de subroutine. Pas vraiment une fonction en tant que telle. Avec juste le nom NOM (et un éventuel pro-
totype), c’est une simple déclaration préalable. Sans NOM, c’est la déclaration d’une fonction anonyme et cela retourne une
valeur : la référence du CODE de la fermeture que vous venez de créer. Voir le manuel perlsub et le manuel perlref pour plus
de détails.
substr EXPR,OFFSET,LONGUEUR,REMPLACEMENT
substr EXPR,OFFSET,LONGUEUR
substr EXPR,OFFSET
Extrait une sous-chaîne de EXPR et la retourne. Le premier caractère est à l’indice 0 ou à ce que vous avez ?xé par $[ (mais
ne le faites pas). Si OFFSET est négatif (ou plus précisément plus petit que $[), le compte a lieu à partir de la ?n de la chaîne.
Si LONGUEUR est omis, retourne tous les caractères jusqu’à la ?n de la chaîne. Si LONGUEUR est négatif, il indique le
nombre de caractères à laisser à la ?n de la chaîne.
Vous pouvez utiliser la fonction substr() comme une lvalue auquel cas EXPR doit aussi être une lvalue. Si vous affec-
tez quelque chose de plus court que LONGUEUR, la chaîne raccourcit et si vous affectez quelque chose de plus long que
LONGUEUR, la chaîne grossit. Pour conserver la même longueur vous pouvez remplir ou couper votre valeur en utilisant
sprintf().
Si OFFSET et LONGUEUR spéci?ent une sous-chaîne qui est partiellement en dehors de la chaîne, seule la partie qui est dans
la chaîne qui est retournée. Si la sous-chaîne est entièrement en dehors de la chaîne, un message d’avertissement (warning) est
produit et la valeur undef est retournée. Lorsque substr() est utilisé en tant que lvalue, spéci?er une sous-chaîne entièrement
en dehors de la chaîne produit une erreur fatale. Voici un exemple illustrant ce comportement :
my $name = ’fred’;
substr($name, 4) = ’dy’;
# $name vaut maintenant ’freddy’
my $null = substr $name, 6, 2;
# retourne ’’ (sans avertissement)
my $oops = substr $name, 7;
# retourne undef, avec avertissement
substr($name, 7) = ’gap’;
# erreur fatale
Un autre moyen d’utiliser substr() comme lvalue est de spéci?er la chaîne de remplacement comme quatrième argument
(REMPLACEMENT). Ceci permet de remplacer une partie de la chaîne en récupérant ce qui y était auparavant en une seule
opération exactement comme avec splice().
symlink OLDFILE,NEWFILE
Crée un nouveau ?chier (NEWFILE) lié symboliquement au vieux ?chier (OLDFILE). Retourne 1 en cas de succès ou 0
autrement. Produit une erreur fatale lors de l’exécution sur les systèmes qui ne supportent pas les liens symboliques. Pour
véri?er cela, utilisez eval :
$symlink_exists =
eval { symlink("",""); 1 };
123

7.1. DESCRIPTION
perlfunc
syscall LISTE
Réalise l’appel système spéci?é comme premier élément de la liste en lui passant les éléments restants comme arguments.
Cela produit une erreur fatale si il n’est pas implémenté. Les arguments sont interprétés de la manière suivante : si un argument
donné est numérique, il est passé comme un entier. Sinon, c’est le pointeur vers la valeur de la chaîne qui est passé. Vous avez
la charge de vous assurer qu’une chaîne est déjà assez longue pour recevoir un résultat qui pourrait y être écrit. Vous ne pouvez
pas utiliser de chaîne littérale (ou autres chaîne en lecture seule) comme argument de syscall() parce que Perl s’assure qu’il
est possible d’écrire dans toutes les chaînes dont il passe les pointeurs. Si votre argument numérique n’est pas un littéral et n’a
jamais été interprété dans un contexte numérique. vous pouvez lui ajouter 0 pour forcer Perl a le voir comme un nombre. Le
code suivant émule la fonction syswrite() :
require ’’;
# peut nécessiter de faire tourner h2ph
$s = "hi there\n";
syscall(&SYS_write, fileno(STDOUT), $s, length $s);
Remarquez que Perl ne peut pas passer plus de 14 arguments à votre appel système, ce qui en pratique suf?t largement.
Syscall retourne la valeur retournée par l’appel système appelé. Si l’appel système échoue, syscall() retourne -1 et posi-
tionne $! (errno). Remarquez que certains appels systèmes peuvent légitimement retourner -1. Le seul moyen de gérer cela
proprement est de faire $!=0 avant l’appel système et de regarder la valeur de $! lorsque syscall retourne -1.
Il y a un problème avec syscall(&SYS_pipe) : cela retourne le numéro du ?chier créé côté lecture du tube. Il n’y a aucun
moyen de récupérer le numéro de ?chier de l’autre côté. Vous pouvez contourner ce problème en utilisant pipe() à la place.
sysopen DESCRIPTEUR,FILENAME,MODE
sysopen DESCRIPTEUR,FILENAME,MODE,PERMS
Ouvre le ?chier dont le nom est donné par FILENAME et l’associe avec DESCRIPTEUR. Si DESCRIPTEUR est une ex-
pression, sa valeur représente le nom du véritable descripteur à utiliser. Cette fonction appelle la fonction open() du système
sous-jacent avec les paramètres FILENAME, MODE et PERMS.
Les valeurs possibles des bits du paramètre MODE sont dépendantes du système; elles sont disponibles via le module standard
Fcntl. Lisez la documentation du open de votre système d’exploitation pour savoir quels sont les bits disponibles. Vous pouvez
combiné plusieurs valeurs en utilisant l’opérateur |.
Quelques-unes des valeurs les plus courantes sont O_RDONLY pour l’ouverture en lecture seule, O_WRONLY pour l’ouverture en
écriture seule, et O_RDWR pour l’ouverture en mode lecture/écriture.
Pour des raisons historiques, quelques valeurs fonctionnent sur la plupart des systèmes supportés par perl : zéro signi?e
lecture seule, un signi?e écriture seule et deux signi?e lecture/écriture. Nous savons que ces valeurs ne fonctionne pas sous
Unix OS/390 ou sur Macintosh; vous ne devriez sans doute pas les utiliser dans du code nouveau.
Si le ?chier nommé FILENAME n’existe pas et que l’appel à open() le crée (typiquement parce que MODE inclut le
?ag O_CREAT) alors la valeur de PERM spéci?e les droits de ce nouveau ?chier. Si vous avez omis l’argument PERM de
sysopen(), Perl utilise la valeur octale 0666. Les valeurs de droits doivent être fournies en octal et sont modi?ées par la
valeur courante du umask de votre process.
Sur la plupart des systèmes, le ?ag O_EXCL permet d’ouvrir un ?chier en mode exclusif. Ce n’est pas du verrouillage : l’exclu-
sivité signi?e ici que si le ?chier existe déjà, sysopen() échoue. O_EXCL l’emporte sur O_TRUNC.
Parfois vous voudrez tronqué un ?chier existant : O_TRUNC.
Vous devriez éviter d’imposer un mode 0644 comme argument de sysopen parce que cela enlève à l’utilisateur la possibilité
de ?xer un umask plus permissif. Voir le titre umask dans ce document pour plus de détails.
Notez que sysopen dépend de la fonction fdopen() de votre bibliothèque C. Sur de nombreux systèmes UNIX, fdopen() est
connue pour échouer si le nombre de descripteurs de ?chiers excède une certaine valeur, typiquement 255. Si vous avez besoin
de plus de descripteurs, pensez à recompiler Perl en utilisant la bibliothèque sfio ou à utiliser le fonction POSIX::open().
Voir le manuel perlopentut pour une initiation à l’ouverture de ?chiers.
sysread DESCRIPTEUR,SCALAIRE,LONGUEUR,OFFSET
sysread DESCRIPTEUR,SCALAIRE,LONGUEUR
Tente de lire LONGUEUR octets de données à partir du DESCRIPTEUR spéci?é en utilisant l’appel système read(2). Les
données lues sont stockées dans la variable SCALAIRE. Passe outre la bibliothèque stdio. Donc le mélange avec d’autres
sortes de lecture/écriture comme print(), write(), seek() ou tell() peut mal se passer parce que habituellement stdio
bufferise les données. Retourne le nombre d’octets réellement lus, 0 à la ?n du ?chier ou undef en cas d’erreur. SCALAIRE
grossira ou réduira a?n que le dernier octet lus soit effectivement le dernier octet du scalaire après la lecture.
Un OFFSET peut être spéci?é pour placer les données lues ailleurs qu’au début de la chaîne. Un OFFSET négatif spéci?e
un emplacement en comptant à partir de la ?n de la chaîne. Un OFFSET positif plus grand que la longueur de SCALAIRE
agrandira la chaîne jusqu’à la taille requise en la remplissant avec des octets "\0" avant de lui ajouter le résultat de la lecture.
Il n’y a pas de fonction syseof(), ce qui n’est pas un mal puisque eof() ne marche pas très bien sur les ?chiers device (comme
les tty). Utilisez sysread() et testez une valeur de retour à zéro pour savoir si c’est terminé.
124

7.1. DESCRIPTION
perlfunc
sysseek DESCRIPTEUR,POSITION,WHENCE
Modi?e la position système d’un DESCRIPTEUR en utilisant l’appel système lseek(2). Cela passe outre la bibliothèque
stdio. Donc le mélange avec d’autres sortes de lecture/écriture (autre que sysread()) comme print(), write(), seek() ou
tell() peut tout casser. DESCRIPTEUR peut être une expression qui donne le nom du descripteur à utiliser. Les valeurs de
WHENCE sont 0 pour mettre la nouvelle position à POSITION, 1 pour la mettre à la position courante plus POSITION et 2
pour la mettre à EOF plus POSITION (typiquement une valeur négative). Pour WHENCE, vous pouvez utiliser les constantes
SEEK_SET, SEEK_CUR et SEEK_END (début de ?chier, position courante, ?n de ?chier) provenant du module Fcntl.
Retourne la nouvelle position ou undef en cas d’échec. Une position nulle est retournée par la valeur "0 but true"; Donc
sysseek() retourne true (vrai) en cas de succès et false (faux) en cas d’échec et vous pouvez encore déterminer facilement la
nouvelle position.
system LISTE
system PROGRAMME LISTE
Fait exactement la même chose que exec LISTE sauf qu’un fork est effectué au préalable et que le process parent attend que
son ?ls ait terminé. Remarquez que le traitement des arguments dépend de leur nombre. Si il y a plus d’un argument dans
LISTE ou si LISTE est un tableau avec plus d’une valeur, system exécute le programme donné comme premier argument
avec comme arguments ceux donnés dans le reste de la liste. Si il n’y a qu’un seul argument dans LISTE et s’il contient des
méta-caractères du shell, il est passé en entier au shell de commandes du systèmes pour être interprété (c’est /bin/sh -c
sur les plates-formes Unix mais cela peut varier sur les autres). Si il ne contient pas de méta-caractères du shell, il est alors
découpé en mots et passé directement à execvp(), ce qui est plus ef?cace.
Depuis la version v5.6.0, Perl tente de vider les tampons de tous les ?chiers ouverts en écriture avant d’effectuer une opération
impliquant un fork() mais cela n’est pas supporté sur toutes les plates-formes (voir le manuel perlport). Pour être plus sûr,
vous devriez positionné la variable $| ($AUTOFLUSH en anglais) ou appelé la méthode autoflush() des objets IO::Handle
pour chacun des descripteurs ouverts.
La valeur retournée est le statut de sortie (exit status) du programme tel que retourné par l’appel wait(). Pour obtenir la valeur
réelle de sortie, il faut le diviser par 256. Voir aussi le titre exec dans ce document. Ce n’est pas ce qu’il faut utiliser pour
capturer la sortie d’une commande. Pour cela regarder les apostrophes inversées (backticks) ou qx// comme décrit dans le
titre ‘CHAINE‘ dans le manuel perlop. Une valeur de retour -1 indique l’échec du lancement du programme ($! en donne la
raison).
Comme exec(), system() vous autorise à dé?nir le nom sous lequel le programme apparaît si vous utilisez la syntaxe
"system PROGRAMME LISTE". Voir le titre exec dans ce document.
Puisque system() et les apostrophes inversées (backticks) bloquent SIGINT et SIGQUIT, tuer le programme qu’ils font tourner
n’interrompra pas votre programme.
@args = ("command", "arg1", "arg2");
system(@args) == 0
or die "system @args failed: $?"
Vous pouvez tester tous les cas possibles d’échec en analysant $? de la manière suivante :
$exit_value
= $? >> 8;
$signal_num
= $? & 127;
$dumped_core = $? & 128;
Lorsque les arguments sont exécutés via le shell système, les résultats et codes de retour sont sujet à tous ses caprices et
capacités. Voir le titre ‘CHAINE‘ dans le manuel perlop et le titre exec dans ce document pour plus de détails.
syswrite DESCRIPTEUR,SCALAIRE,LONGUEUR,OFFSET
syswrite DESCRIPTEUR,SCALAIRE,LONGUEUR
syswrite DESCRIPTEUR,SCALAIRE
Essaye d’écrire LONGUEUR octets de données provenant de la variable SCALAIRE sur le DESCRIPTEUR spéci?é en
utilisant l’appel système write(2). Si LONGUEUR n’est pas spéci?é, c’est la valeur entière de SCALAIRE qui est écrite.
Passe outre la bibliothèque stdio. Donc le mélange avec d’autres sortes de lecture/écriture (autre que sysread()) comme
print(), write(), seek() ou tell() peut mal se passer parce que habituellement stdio bufferise les données. Retourne
le nombre d’octets réellement écrits ou undef en cas d’erreur. Si LONGUEUR est plus grand que la quantité de données
disponibles dans SCALAIRE après OFFSET, seules les données disponibles sont écrites.
Un OFFSET peut être spéci?é pour lire les données à écrire à partir d’autre chose que le début du scalaire. Un OFFSET
négatif calcule l’emplacement en comptant à partir de la ?n de la chaîne. Au cas où SCALAIRE est vide, vous pouvez utiliser
OFFSET mais uniquement avec la valeur zéro.
tell DESCRIPTEUR
125

7.1. DESCRIPTION
perlfunc
tell
Retourne la position courante de DESCRIPTEUR. DESCRIPTEUR peut être une expression dont la valeur donne le nom du
descripteurs réel. Si DESCRIPTEUR est omis, on utilise le dernier ?chier lu.
Il n’y a pas de fonction systell. Utilisez sysseek(FH, 0, 1) à la place.
telldir DIRHANDLE
Retourne la position courante du dernier readdir() effectué sur DIRHANDLE. La valeur retournée peut être fournie à
seekdir() pour accéder à un endroit particulier dans ce répertoire. Pose les mêmes problèmes que l’appel système corres-
pondant.
tie VARIABLE,CLASSNAME,LISTE
Cette fonction relie une variable à une classe d’un package qui fournit l’implémentation de cette variable. VARIABLE est le
nom de la variable à relier. CLASSNAME est le nom de la classe implémentant les objets du type correct. Tout argument sup-
plémentaire est passé tel quel à la méthode "new()" de la classe (à savoir TIESCALAR, TIEARRAY ou TIEHASH). Typiquement,
ce sont des arguments tels que ceux passés à la fonction C dbm_open(). L’objet retourné par la méthode "new()" est aussi
retourné par la fonction tie() ce qui est pratique si vous voulez accéder à d’autres méthodes de CLASSNAME.
Remarquez que des fonctions telles que keys() et values() peuvent retourner des listes énormes lorsqu’elles sont utilisées
sur de gros objets comme des ?chiers DBM. Vous devriez plutôt utiliser la fonction each() pour les parcourir. Exemple :
# print out history file offsets
use NDBM_File;
tie(%HIST, ’NDBM_File’, ’/usr/lib/news/history’, 1, 0);
while (($key,$val) = each %HIST) {
print $key, ’ = ’, unpack(’L’,$val), "\n";
}
untie(%HIST);
Une classe implémentant une table de hachage devrait dé?nir les méthodes suivantes :
TIEHASH classname, LISTE
FETCH this, key
STORE this, key, value
DELETE this, key
CLEAR this
EXISTS this, key
FIRSTKEY this
NEXTKEY this, lastkey
DESTROY this
Une classe implémentant un tableau devrait dé?nir les méthodes suivantes :
TIEARRAY classname, LISTE
FETCH this, key
STORE this, key, value
FETCHSIZE this
STORESIZE this, count
CLEAR this
PUSH this, LISTE
POP this
SHIFT this
UNSHIFT this, LISTE
SPLICE this, offset, length, LISTE
EXTEND this, count
DESTROY this
Une classe implémentant un descripteur de ?chier devrait dé?nir les méthodes suivantes :
TIEHANDLE classname, LISTE
READ this, scalar, length, offset
READLINE this
GETC this
WRITE this, scalar, length, offset
PRINT this, LISTE
PRINTF this, format, LISTE
126

7.1. DESCRIPTION
perlfunc
CLOSE this
DESTROY this
Une classe implémentant un scalaire devrait dé?nir les méthodes suivantes :
TIESCALAR classname, LISTE
DESTROY this
FETCH this,
STORE this, value
Il n’est pas absolument nécessaire d’implémenter toutes les méthodes décrites ci-dessus. Voir le manuel perltie, le manuel
Tie::Hash, le manuel Tie::Array, le manuel Tie::Scalar, et le manuel Tie::Handle.
Au contraire de dbmopen(), la fonction tie() n’effectue pas pour vous le ’use’ ou le ’require’ du module – vous devez le
faire vous-même explicitement. Voir les modules DB_File ou Con?g pour des utilisations intéressantes de tie().
Pour de plus amples informations, voir le manuel perltie et le titre tied VARIABLE dans ce document.
tied VARIABLE
Retourne une référence vers l’objet caché derrière VARIABLE (la même valeur que celle retournée par l’appel tie() qui a
lié cette variable à un package). Retourne la valeur undef si VARIABLE n’est pas lié à un package.
time
Retourne le nombre de secondes écoulées depuis ce que le système considère comme étant l’origine des temps (C’est le 1er
janvier 1904 à minuit pour MacOS et le 1er janvier 1970 à minuit pour la plupart des autre systèmes). Peut servir comme
argument de gmtime() et de localtime().
Pour mesurer le temps avec une meilleurs granularité que la seconde, vous pouvez utiliser le module Time::HiRes disponible
sur CPAN ou, si vous avec gettimeofday(2), vous pouvez utiliser l’interface syscall de Perl. Voir le manuel perlfaq8 pour les
détails.
times
Retourne une liste de quatre éléments donnant le temps utilisateur et système en secondes, pour ce process et pour les enfants
de ce process.
($user,$system,$cuser,$csystem) = times;
tr///
L’opérateur de translittération. La même chose que y///. Voir le manuel perlop.
truncate DESCRIPTEUR,LONGUEUR
truncate EXPR,LONGUEUR
Tronque le ?chier ouvert par DESCRIPTEUR ou nommé par EXPR à la taille LONGUEUR spéci?ée. Produit une erreur fatale
si la troncature n’est pas implémentée sur votre système. Retourne true (vrai) en cas de succès ou la valeur undef autrement.
uc EXPR
uc
Retourne la version en majuscule de EXPR. C’est la fonction interne qui implémente la séquence d’échappement \U des
chaînes entre guillemets. Respecte le locale LC_CTYPE courant si use locale est actif. Voir le manuel perllocale. Avec
Unicode (use utf8), utilise la table des correspondances minuscules/majuscules du standard Unicode. (Ne gère pas la table
spéci?que aux majuscules apparaissant en début de mot. Voir le manuel uc?rst pour cela.)
Si EXPR est omis, s’applique à $_.
uc?rst EXPR
uc?rst
Retourne la valeur de EXPR avec le premier caractère en majuscule. C’est la fonction interne qui implémente la séquence
d’échappement \u des chaînes entre guillemets. Respecte le locale LC_CTYPE courant si use locale est actif. Voir le
manuel perllocale et le manuel utf8.
Si EXPR est omis, s’applique à $_.
umask EXPR
umask
Positionne le umask du process à EXPR et retourne la valeur précédente. Si EXPR est omis, retourne la valeur courante du
umask.
Les droits Unix rwxr-x-- sont représentés par trois ensembles de trois bits ou par trois nombres octaux : 0750 (le 0 initial
indique une valeur octale et ne fait pas partie des chiffres). La valeur de umask est un tel nombre qui représente les bits
de permissions désactivés. Les valeurs de permissions (ou "droits" ou "mode") que vous passez à mkdir ou sysopen sont
127

7.1. DESCRIPTION
perlfunc
modi?ées par votre umask. Par exemple, si vous dites à sysopen de créer un ?chier avec les droits 0777 et si votre umask vaut
0022 alors le ?chier sera réellement créé avec les droits 0755. Si votre umask vaut 0027 (le groupe ne peut écrire ; les autres
ne peuvent ni lire, ni écrire, ni exécuter) alors passer 0666 à sysopen créera une ?chier avec les droits 0640 (0666 &˜ 027
vaut 0640).
Voici quelques conseils : fournissez un mode de création de 0666 pour les ?chiers normaux (dans sysopen) et de 0777 pour
les répertoires (dans mkdir) et les ?chiers exécutables. Cela donne la liberté à l’utilisateur de choisir : si il veut des ?chiers
protégés, il peut choisir un umask de 022 ou 027 ou même le umask particulièrement antisocial 077. Les programmes peuvent
rarement (si ce n’est jamais) prendre des décisions de polices mieux que l’utilisateur. L’exception concerne les ?chiers qui
doivent être gardés privé : ?chiers de mail, ?chiers de cookies des navigateurs, ?chiers .rhosts et autres.
Si umask(2) n’est pas implémenté sur votre système et que vous êtes en train de restreindre les droits d’accès pour vous-même
(i.e. (EXPR & 0700) > 0), cela produit une erreur fatale lors de l’exécution. Si umask(2) n’est pas implémenté et que vous ne
modi?ez pas vos propres droits d’accès, retourne undef.
Souvenez-vous que umask est un nombre, habituellement donné en octal ; Ce n’est pas une chaîne de chiffres en octal. Voir
aussi le titre oct dans ce document, si vous disposez d’une chaîne.
undef EXPR
undef
Donne à EXPR la valeur indé?nie (undef). EXPR doit être une lvalue. À n’utiliser que sur des scalaires, des tableaux (en
utilisant @), des tables de hachage (en utilisant %), des subroutines (en utilisant &) ou des typeglob (en utilisant *). (Dire undef
$hash{$key} ne fera probablement pas ce que vous espérez sur la plupart des variables prédé?nies ou sur les liste de valeurs
DBM. Ne le faites donc pas; voir le titre delete dans ce document.) Retourne toujours la valeur undef. Vous pouvez omettre
EXPR auquel cas rien ne sera indé?nie mais vous récupérerez encore la valeur undef a?n, par exemple, de la retourner depuis
une subroutine, de l’affecter à une variable ou de la passer comme argument. Exemples :
undef $foo;
undef $bar{’blurfl’};
# À comparer à : delete $bar{’blurfl’};
undef @ary;
undef %hash;
undef &mysub;
undef *xyz;
# détruit $xyz, @xyz, %xyz, &xyz, etc.
return (wantarray ? (undef, $errmsg) : undef) if $they_blew_it;
select undef, undef, undef, 0.25;
($a, $b, undef, $c) = &foo;
# Ignorer la troisième valeur retournée
Remarquez que c’est un opérateur unaire et non un opérateur de liste.
unlink LISTE
unlink
Efface une liste de ?chiers. Retourne le nombre de ?chiers effacés avec succès.
$cnt = unlink ’a’, ’b’, ’c’;
unlink @goners;
unlink <*.bak>;
Remarque : unlink() n’effacera pas de répertoires à moins que vous ne soyez le super-utilisateur (root) et que l’option -U
soit donnée à Perl. Même si ces conditions sont remplies, soyez conscient que l’effacement d’un répertoire par unlink peut
endommager votre système de ?chiers. Utilisez rmdir() à la place.
Si LISTE est omis, s’applique à $_.
unpack TEMPLATE,EXPR
unpack() réalise l’opération inverse de pack() : il prend une chaîne représentant une structure, la décompose en une liste de
valeurs et retourne la liste de ces valeurs. (Dans un contexte scalaire, il retourne simplement la première valeur produite.)
La chaîne est découpé en morceaux selon le format TEMPLATE fourni. Chaque morceau est converti séparément en une
valeur. Typiquement, soit la chaîne est le résultat d’un pack soit les octets de la chaîne représentent un structure C d’un certain
type.
Le TEMPLATE a le même format que pour la fonction pack(). Voici une subroutine qui extrait une sous-chaîne :
sub substr {
my($what,$where,$howmuch) = @_;
unpack("x$where a$howmuch", $what);
}
et un autre exemple :
128

7.1. DESCRIPTION
perlfunc
sub ordinal { unpack("c",$_[0]); } # identique à ord()
En plus, vous pouvez pré?xé un champ avec un %<nombre> pour indiquez que vous voulez un checksum des items sur
<nombre> bits à la place des items eux-mêmes. Par défaut, c’est un checksum sur 16 bits. Le checksum est calculé en addition-
nant les valeurs numériques des valeurs extraites (pour les champs alphanumériques, c’est la somme des ord($caractere)
qui est prise et pour les champs de bits, c’est la somme des 1 et des 0).
Par exemple, le code suivant calcule le même nombre que le programme sum System V :
$checksum = do {
local $/;
# slurp!
unpack("%32C*",<>) % 65535;
};
Le code suivant calcule de manière ef?cace le nombre de bits à un dans un vecteur de bits :
$setbits = unpack("%32b*", $selectmask);
Les formats p et P doivent être utilisés avec précautions. Puisque Perl n’a aucun moyen de véri?er que les valeurs passées à
unpack() correspondent à des emplacements mémoires valides, le passage d’un pointeur dont on n’est pas sûr de la validité
peut avoir des conséquences désastreuses.
Si la valeur de répétition d’un champ est plus grande que ce que le reste de la chaîne d’entrée autorise, la valeur est diminuée.
Si la chaîne d’entrée est trop longue que ce qui est décrit par TEMPLATE, le reste est ignoré.
Voir le titre pack dans ce document pour plus d’exemples et de remarques.
untie VARIABLE
Casse le lien entre une variable et un package. (Voir tie().)
unshift TABLEAU,LISTE
Fait le contraire de shift(). Ou le contraire de push(), selon le point de vue. Ajoute la liste LISTE au début du tableau
TABLEAU et retourne le nouveau nombre d’éléments du tableau.
unshift(ARGV, ’-e’) unless $ARGV[0] =~ /^-/;
Remarquez que LISTE est ajoutée d’un seul coup et non élément par élément. Donc les éléments restent dans le même ordre.
Utilisez reverse() pour faire le contraire.
use Module VERSION LISTE
use Module VERSION
use Module LISTE
use Module
use VERSION
Importe dans le package courant quelques "sémantiques" du module spéci?é, généralement en les attachant à certains noms
de subroutines ou de variables de votre package. C’est exactement équivalent à :
BEGIN { require Module; import Module LISTE; }
sauf que Module doit être un mot (bareword).
VERSION, qui peut être spéci?é sous la forme v5.6.1, demande que la version courante de Perl ($ˆV ou $PERL_VERSION)
soit au moins aussi récente que VERSION. (Pour des raisons de compatibilité avec de vieilles versions Perl, un littéral numé-
rique sera aussi interprété comme une VERSION.) Si la version de l’interpréteur Perl courant est plus petite que VERSION
alors un message est af?ché et Perl se termine immédiatement sans même essayer de lire le reste du ?chier. Comparez avec le
titre require dans ce document qui peut faire la même chose mais lors de l’exécution.
use v5.6.1;
# vérification de version à la compilation
use 5.6.1;
# idem
use 5.005_03;
# numéro de version numérique
C’est pratique si vous devez véri?er la version courante de Perl avant d’utiliser (via use) des modules qui ont changé de
manière incompatible depuis les anciennes versions. (Nous essayons de le faire le moins souvent possible).
Le BEGIN force le require et le import lors de la compilation. Le require assure que le module est chargé en mémoire
si il ne l’avait pas déjà été. import n’est pas une fonction interne – c’est juste un appel à une méthode statique ordinaire
dans le package "Module" pour lui demander d’importer dans le package courant la liste de ses fonctionnalités. Le module
peut implémenter sa méthode import() comme il le veut, bien que la plupart des modules préfèrent simplement la dé?nir
par héritage de la classe Exporter qui est dé?nie dans le module Exporter. Voir le manuel Exporter. Si aucune méthode
import() ne peut être trouvée alors l’appel est ignoré.
Si vous ne voulez pas que votre espace de noms soit modi?é, fournissez explicitement une liste vide :
129

7.1. DESCRIPTION
perlfunc
use Module ();
C’est exactement équivalent à :
BEGIN { require Module }
Si l’argument VERSION est présent entre Module et LISTE alors use appelle le méthode VERSION de la classe Module avec
la version spéci?é comme argument. La méthode VERSION par défaut, héritée de la classe Universal, crie (via croak) si la
version demandée est plus grande que celle fournie par la variable $Module::VERSION. Remarquez qu’il n’y a pas de virgule
après VERSION !
À nouveau, il y a une différence entre omettre LISTE (import appelé sans argument) et fournir une LISTE explicitement vide
() (import n’est pas appelé).
Puisque c’est une interface largement ouverte, les pragmas (les directives du compilateur) sont aussi implémentés en utilisant
ce moyen. Les pragmas actuellement implémentés sont :
use integer;
use diagnostics;
use sigtrap
qw(SEGV BUS);
use strict
qw(subs vars refs);
use subs
qw(afunc blurfl);
use warnings qw(all);
Certains d’entre eux sont des pseudo-modules qui importent de nouvelles sémantiques uniquement dans la portée du bloc
courant (comme strict or integer) contrairement aux modules ordinaires qui importent des symboles dans le package
courant (qui sont donc effectifs jusqu’à la ?n du ?chier lui-même).
Il y a une commande "no" permettant de "désimporter" des choses importées par use, i.e. elle appelle unimport Module
LISTE à la place de import.
no integer;
no strict ’refs’;
no warnings;
Si aucune méthode unimport() ne peut être trouvée l’appel échoue avec une erreur fatale.
Voir le manuel perlmod pour une liste des modules et pragmas standard.
utime LISTE
Change la date d’accès et de modi?cation de chaque ?chier d’une liste de ?chiers. Les deux premiers éléments de la liste
doivent être des dates NUMÉRIQUES d’accès et de modi?cation dans cet ordre. Retourne le nombre de ?chiers modi?és avec
succès. La date de modi?cation de l’inode de chaque ?chier est mis à l’heure courante. Le code suivant a exactement le même
effet que la commande "touch" si les ?chiers existent déjà :
#!/usr/bin/perl
$now = time;
utime $now, $now, @ARGV;
values HASH
Retourne la liste de toutes les valeurs contenues dans la table de hachage HASH. (Dans un contexte scalaire, retourne le
nombre de valeurs.) Les valeurs sont apparemment retournées dans un ordre aléatoire qui pourrait changer avec les nouvelles
versions de Perl mais c’est le même ordre que celui produit par les fonctions keys() ou each() sur la même table de hachage
(tant qu’elle n’est pas modi?ée).
Remarquez que vous ne pouvez pas changer les valeurs de la table par ce moyen car la liste retournée est juste une copie des
valeurs. Vous devez utilisez un slice de table de hachage pour cela puisqu’il produit une lvalue alors que values() ne l’est pas.
for (values %hash)
{ s/foo/bar/g }
# ECHEC !
for (@hash{keys %hash}) { s/foo/bar/g }
# ok
Comme effet de bord, il réinitialise l’itérateur de HASH. Voir aussi keys, each et sort.
vec EXPR,OFFSET,BITS
Traite la chaîne contenue dans EXPR comme un vecteur d’entiers non signés et retourne la valeur du champ de bits spéci?é
par OFFSET. BITS spéci?e le nombre de bits qui est occupé par chaque entrée dans le vecteur de bits. Cela doit être une
puissance de deux entre 1 et 32
Si BITS vaut 8, les "éléments" coïncident avec les octets de la chaîne d’entrée.
130

7.1. DESCRIPTION
perlfunc
Si BITS vaut 16 ou plus, les octets de la chaîne d’entrée sont groupés par morceau de taille BITS/8 puis chaque groupe
est converti en un nombre comme le feraient pack() et unpack() avec les formats big-endian n/N. Voir le titre pack dans ce
document pour plus de détails.
Si BITS est 4 ou moins, la chaîne est découpée en octets puis les bits de chaque octet sont découpés en 8/BITS groupes. Les
bits d’un octet sont numérotés à la manière little-endian comme dans 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80. Par
exemple, le découpage d’un seul octet d’entrée chr(0x36) en deux groupes donnera la liste (0x6, 0x3) ; son découpage en
4 groupes donnera (0x2, 0x1, 0x3, 0x0).
vec() peut aussi être affecté auquel cas les parenthèses sont nécessaires pour donner les bonnes priorités :
vec($image, $max_x * $x + $y, 8) = 3;
Si l’élément sélectionné est en dehors de la chaîne, la valeur retournée sera zéro. Si, au contraire, vous cherchez à écrire dans
un élément en dehors de la chaîne, Perl agrandira suf?samment la chaîne au préalable en la complétant par des octets nuls.
Les vecteurs créés par vec() peuvent aussi être manipulés par les opérateurs logiques |, & et ˆ qui supposent qu’une opération
bit à bit est voulue lorsque leurs deux opérandes sont des chaînes. Voir le titre Opérateurs bit à bit sur les chaînes dans le
manuel perlop.
Le code suivant construit une chaîne ASCII disant ’PerlPerlPerl’. Les commentaires montrent la chaîne après chaque pas.
Remarquez que ce code fonctionne de la même manière sur des machines big-endian ou little-endian.
my $foo = ’’;
vec($foo,
0, 32) = 0x5065726C;
# ’Perl’
# $foo eq "Perl" eq "\x50\x65\x72\x6C", 32 bits
print vec($foo, 0, 8);
# affiche 80 == 0x50 == ord(’P’)
vec($foo,
2, 16) = 0x5065;
# ’PerlPe’
vec($foo,
3, 16) = 0x726C;
# ’PerlPerl’
vec($foo,
8,
8) = 0x50;
# ’PerlPerlP’
vec($foo,
9,
8) = 0x65;
# ’PerlPerlPe’
vec($foo, 20,
4) = 2;
# ’PerlPerlPe’
. "\x02"
vec($foo, 21,
4) = 7;
# ’PerlPerlPer’
# ’r’ is "\x72"
vec($foo, 45,
2) = 3;
# ’PerlPerlPer’
. "\x0c"
vec($foo, 93,
1) = 1;
# ’PerlPerlPer’
. "\x2c"
vec($foo, 94,
1) = 1;
# ’PerlPerlPerl’
# ’l’ is "\x6c"
Pour transformer un vecteur de bits en une chaîne ou en un tableau de 0 et de 1, utilisez ceci :
$bits = unpack("b*", $vector);
@bits = split(//, unpack("b*", $vector));
Si vous connaissez précisément la longueur du vecteur, vous pouvez l’utiliser à la place de *.
Voici un exemple qui illustre comment le bits sont réellement placés :
#!/usr/bin/perl -wl
print <<’EOT’;
0
1
2
3
unpack("V",$_) 01234567890123456789012345678901
------------------------------------------------------------------
EOT
for $w (0..3) {
$width = 2**$w;
for ($shift=0; $shift < $width; ++$shift) {
for ($off=0; $off < 32/$width; ++$off) {
$str = pack("B*", "0"x32);
$bits = (1<<$shift);
vec($str, $off, $width) = $bits;
$res = unpack("b*",$str);
$val = unpack("V", $str);
write;
}
}
}
131

7.1. DESCRIPTION
perlfunc
format STDOUT =
vec($_,@#,@#) = @<< == @######### @>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
$off, $width, $bits, $val, $res
.
__END__
Indépendamment de l’architecture de la machine qui exécute ce code, l’exemple ci-dessus devrait produire la table suivante :
0
1
2
3
unpack("V",$_) 01234567890123456789012345678901
------------------------------------------------------------------
vec($_, 0, 1) = 1
==
1 10000000000000000000000000000000
vec($_, 1, 1) = 1
==
2 01000000000000000000000000000000
vec($_, 2, 1) = 1
==
4 00100000000000000000000000000000
vec($_, 3, 1) = 1
==
8 00010000000000000000000000000000
vec($_, 4, 1) = 1
==
16 00001000000000000000000000000000
vec($_, 5, 1) = 1
==
32 00000100000000000000000000000000
vec($_, 6, 1) = 1
==
64 00000010000000000000000000000000
vec($_, 7, 1) = 1
==
128 00000001000000000000000000000000
vec($_, 8, 1) = 1
==
256 00000000100000000000000000000000
vec($_, 9, 1) = 1
==
512 00000000010000000000000000000000
vec($_,10, 1) = 1
==
1024 00000000001000000000000000000000
vec($_,11, 1) = 1
==
2048 00000000000100000000000000000000
vec($_,12, 1) = 1
==
4096 00000000000010000000000000000000
vec($_,13, 1) = 1
==
8192 00000000000001000000000000000000
vec($_,14, 1) = 1
==
16384 00000000000000100000000000000000
vec($_,15, 1) = 1
==
32768 00000000000000010000000000000000
vec($_,16, 1) = 1
==
65536 00000000000000001000000000000000
vec($_,17, 1) = 1
==
131072 00000000000000000100000000000000
vec($_,18, 1) = 1
==
262144 00000000000000000010000000000000
vec($_,19, 1) = 1
==
524288 00000000000000000001000000000000
vec($_,20, 1) = 1
==
1048576 00000000000000000000100000000000
vec($_,21, 1) = 1
==
2097152 00000000000000000000010000000000
vec($_,22, 1) = 1
==
4194304 00000000000000000000001000000000
vec($_,23, 1) = 1
==
8388608 00000000000000000000000100000000
vec($_,24, 1) = 1
==
16777216 00000000000000000000000010000000
vec($_,25, 1) = 1
==
33554432 00000000000000000000000001000000
vec($_,26, 1) = 1
==
67108864 00000000000000000000000000100000
vec($_,27, 1) = 1
==
134217728 00000000000000000000000000010000
vec($_,28, 1) = 1
==
268435456 00000000000000000000000000001000
vec($_,29, 1) = 1
==
536870912 00000000000000000000000000000100
vec($_,30, 1) = 1
== 1073741824 00000000000000000000000000000010
vec($_,31, 1) = 1
== 2147483648 00000000000000000000000000000001
vec($_, 0, 2) = 1
==
1 10000000000000000000000000000000
vec($_, 1, 2) = 1
==
4 00100000000000000000000000000000
vec($_, 2, 2) = 1
==
16 00001000000000000000000000000000
vec($_, 3, 2) = 1
==
64 00000010000000000000000000000000
vec($_, 4, 2) = 1
==
256 00000000100000000000000000000000
vec($_, 5, 2) = 1
==
1024 00000000001000000000000000000000
vec($_, 6, 2) = 1
==
4096 00000000000010000000000000000000
vec($_, 7, 2) = 1
==
16384 00000000000000100000000000000000
vec($_, 8, 2) = 1
==
65536 00000000000000001000000000000000
vec($_, 9, 2) = 1
==
262144 00000000000000000010000000000000
vec($_,10, 2) = 1
==
1048576 00000000000000000000100000000000
vec($_,11, 2) = 1
==
4194304 00000000000000000000001000000000
vec($_,12, 2) = 1
==
16777216 00000000000000000000000010000000
vec($_,13, 2) = 1
==
67108864 00000000000000000000000000100000
vec($_,14, 2) = 1
==
268435456 00000000000000000000000000001000
vec($_,15, 2) = 1
== 1073741824 00000000000000000000000000000010
vec($_, 0, 2) = 2
==
2 01000000000000000000000000000000
vec($_, 1, 2) = 2
==
8 00010000000000000000000000000000
132

7.1. DESCRIPTION
perlfunc
vec($_, 2, 2) = 2
==
32 00000100000000000000000000000000
vec($_, 3, 2) = 2
==
128 00000001000000000000000000000000
vec($_, 4, 2) = 2
==
512 00000000010000000000000000000000
vec($_, 5, 2) = 2
==
2048 00000000000100000000000000000000
vec($_, 6, 2) = 2
==
8192 00000000000001000000000000000000
vec($_, 7, 2) = 2
==
32768 00000000000000010000000000000000
vec($_, 8, 2) = 2
==
131072 00000000000000000100000000000000
vec($_, 9, 2) = 2
==
524288 00000000000000000001000000000000
vec($_,10, 2) = 2
==
2097152 00000000000000000000010000000000
vec($_,11, 2) = 2
==
8388608 00000000000000000000000100000000
vec($_,12, 2) = 2
==
33554432 00000000000000000000000001000000
vec($_,13, 2) = 2
==
134217728 00000000000000000000000000010000
vec($_,14, 2) = 2
==
536870912 00000000000000000000000000000100
vec($_,15, 2) = 2
== 2147483648 00000000000000000000000000000001
vec($_, 0, 4) = 1
==
1 10000000000000000000000000000000
vec($_, 1, 4) = 1
==
16 00001000000000000000000000000000
vec($_, 2, 4) = 1
==
256 00000000100000000000000000000000
vec($_, 3, 4) = 1
==
4096 00000000000010000000000000000000
vec($_, 4, 4) = 1
==
65536 00000000000000001000000000000000
vec($_, 5, 4) = 1
==
1048576 00000000000000000000100000000000
vec($_, 6, 4) = 1
==
16777216 00000000000000000000000010000000
vec($_, 7, 4) = 1
==
268435456 00000000000000000000000000001000
vec($_, 0, 4) = 2
==
2 01000000000000000000000000000000
vec($_, 1, 4) = 2
==
32 00000100000000000000000000000000
vec($_, 2, 4) = 2
==
512 00000000010000000000000000000000
vec($_, 3, 4) = 2
==
8192 00000000000001000000000000000000
vec($_, 4, 4) = 2
==
131072 00000000000000000100000000000000
vec($_, 5, 4) = 2
==
2097152 00000000000000000000010000000000
vec($_, 6, 4) = 2
==
33554432 00000000000000000000000001000000
vec($_, 7, 4) = 2
==
536870912 00000000000000000000000000000100
vec($_, 0, 4) = 4
==
4 00100000000000000000000000000000
vec($_, 1, 4) = 4
==
64 00000010000000000000000000000000
vec($_, 2, 4) = 4
==
1024 00000000001000000000000000000000
vec($_, 3, 4) = 4
==
16384 00000000000000100000000000000000
vec($_, 4, 4) = 4
==
262144 00000000000000000010000000000000
vec($_, 5, 4) = 4
==
4194304 00000000000000000000001000000000
vec($_, 6, 4) = 4
==
67108864 00000000000000000000000000100000
vec($_, 7, 4) = 4
== 1073741824 00000000000000000000000000000010
vec($_, 0, 4) = 8
==
8 00010000000000000000000000000000
vec($_, 1, 4) = 8
==
128 00000001000000000000000000000000
vec($_, 2, 4) = 8
==
2048 00000000000100000000000000000000
vec($_, 3, 4) = 8
==
32768 00000000000000010000000000000000
vec($_, 4, 4) = 8
==
524288 00000000000000000001000000000000
vec($_, 5, 4) = 8
==
8388608 00000000000000000000000100000000
vec($_, 6, 4) = 8
==
134217728 00000000000000000000000000010000
vec($_, 7, 4) = 8
== 2147483648 00000000000000000000000000000001
vec($_, 0, 8) = 1
==
1 10000000000000000000000000000000
vec($_, 1, 8) = 1
==
256 00000000100000000000000000000000
vec($_, 2, 8) = 1
==
65536 00000000000000001000000000000000
vec($_, 3, 8) = 1
==
16777216 00000000000000000000000010000000
vec($_, 0, 8) = 2
==
2 01000000000000000000000000000000
vec($_, 1, 8) = 2
==
512 00000000010000000000000000000000
vec($_, 2, 8) = 2
==
131072 00000000000000000100000000000000
vec($_, 3, 8) = 2
==
33554432 00000000000000000000000001000000
vec($_, 0, 8) = 4
==
4 00100000000000000000000000000000
vec($_, 1, 8) = 4
==
1024 00000000001000000000000000000000
vec($_, 2, 8) = 4
==
262144 00000000000000000010000000000000
vec($_, 3, 8) = 4
==
67108864 00000000000000000000000000100000
vec($_, 0, 8) = 8
==
8 00010000000000000000000000000000
vec($_, 1, 8) = 8
==
2048 00000000000100000000000000000000
133

7.1. DESCRIPTION
perlfunc
vec($_, 2, 8) = 8
==
524288 00000000000000000001000000000000
vec($_, 3, 8) = 8
==
134217728 00000000000000000000000000010000
vec($_, 0, 8) = 16
==
16 00001000000000000000000000000000
vec($_, 1, 8) = 16
==
4096 00000000000010000000000000000000
vec($_, 2, 8) = 16
==
1048576 00000000000000000000100000000000
vec($_, 3, 8) = 16
==
268435456 00000000000000000000000000001000
vec($_, 0, 8) = 32
==
32 00000100000000000000000000000000
vec($_, 1, 8) = 32
==
8192 00000000000001000000000000000000
vec($_, 2, 8) = 32
==
2097152 00000000000000000000010000000000
vec($_, 3, 8) = 32
==
536870912 00000000000000000000000000000100
vec($_, 0, 8) = 64
==
64 00000010000000000000000000000000
vec($_, 1, 8) = 64
==
16384 00000000000000100000000000000000
vec($_, 2, 8) = 64
==
4194304 00000000000000000000001000000000
vec($_, 3, 8) = 64
== 1073741824 00000000000000000000000000000010
vec($_, 0, 8) = 128 ==
128 00000001000000000000000000000000
vec($_, 1, 8) = 128 ==
32768 00000000000000010000000000000000
vec($_, 2, 8) = 128 ==
8388608 00000000000000000000000100000000
vec($_, 3, 8) = 128 == 2147483648 00000000000000000000000000000001
wait
Se comporte comme l’appel système wait(2) sur votre système : attend qu’un process ?ls se termine et retourne le pid de ce
process ou -1 si il n’y a pas de process ?ls. Le statut est retourné par $?. Remarquez qu’une valeur de retour -1 peut signi?er
que les process ?ls ont été automatiquement collectés tel que décrit dans le manuel perlipc.
waitpid PID,FLAGS
Attend qu’un process ?ls particulier se termine et retourne le pid de ce process ou -1 si ce process n’existe pas. Sur certains
système, une valeur 0 signi?e qu’il y a encore des process actifs. Le statut est retourné par $?. Si vous dites :
use POSIX ":sys_wait_h";
#
do {
$kid = waitpid(-1,&WNOHANG);
} until $kid == -1;
alors vous pouvez réaliser une attente non bloquante sur plusieurs process. Les attentes non bloquantes sont disponibles sur les
machines qui connaissent l’un des deux appels système waitpid(2) ou wait4(2). Par contre, l’attente d’un process particulier
avec FLAGS à 0 est implémenté partout. (Perl émule l’appel système en se souvenant des valeurs du statut des process qui ont
terminé mais qui n’ont pas encore été collectées par le script Perl.)
Remarquez que sur certains systèmes, une valeur de retour -1 peut signi?er que les process ?ls ont été automatiquement
collectés. Voir le manuel perlipc pour les détails et d’autres exemples.
wantarray
Retourne true (vrai) si le contexte d’appel de la subroutine en cours d’exécution attend une liste de valeurs. Retourne false
(faux) si le contexte attend un scalaire. Retourne la valeur undef si le contexte n’attend aucune valeur ("void context" ou
contexte vide).
return unless defined wantarray;
# inutile d’en faire plus
my @a = complex_calculation();
return wantarray ? @a : "@a";
Cette fonction aurait dû s’appeler wantlist().
warn LISTE
Produit un message d’erreur sur STDERR exactement comme die() mais ne quitte pas et ne lance pas d’exception.
Si LISTE est vide et si $@ contient encore une valeur (provenant par exemple d’un eval précédent) alors cette valeur est utilisée
après y avoir ajouté "\t caught". C’est pratique pour s’approcher d’un comportement presque similaire à die().
Si $@ est vide alors la chaîne "Warning: Something’s wrong" (N.d.t: "Attention: quelque chose va mal") est utili-
sée.
Aucune message n’est af?ché si une subroutine est attachée à $SIG{__WARN__}. C’est de la responsabilité de cette subroutine
de gérer le message comme elle le veut (en le convertissant en un die() par exemple). La plupart des subroutine du genre
devraient s’arranger pour af?cher réellement les messages qu’elles ne sont pas prêtes à recevoir en appelant à nouveau warn().
Remarquez que cela fonctionne sans produire une boucle sans ?n puisque les subroutines attachées à __WARN__ ne sont pas
appelés à partir d’une subroutine attachée.
134

7.2. VERSION FRANÇAISE
perlfunc
Ce comportement est complètement différent de celui des subroutine attachées à $SIG{__DIE__} (qui ne peuvent pas suppri-
mer le texte d’erreur mais seulement le remplacer en appelant à nouveau die()).
L’utilisation d’une subroutine attachée à __WARN__ fournit un moyen puissant pour supprimer tous les messages d’avertisse-
ment (même ceux considérés comme obligatoires). Un exemple :
# supprime *tous* les messages d’avertissement lors de la compilation
BEGIN { $SIG{’__WARN__’} = sub { warn $_[0] if $DOWARN } }
my $foo = 10;
my $foo = 20;
# pas d’avertissement pour la duplication de
# $foo  mais c’est ce qu’on voulait !
# pas de messages d’avertissement avant ici
$DOWARN = 1;
# messages d’avertissement à partir d’ici
warn "\$foo is alive and $foo!";
# devrait apparaître
Voir le manuel perlvar pour plus de détails sur la modi?cation de entrées de %SIG et pour plus d’exemples. Voir le module
Carp pour d’autres sortes d’avertissement utilisant les fonctions carp() et cluck().
write DESCRIPTEUR
write EXPR
write
Écrit un enregistrement formaté (éventuellement multi-lignes) vers le DESCRIPTEUR spéci?é en utilisant le format associé à
ce ?chier. Par défaut, le format pour un ?chier est celui qui a le même nom que le descripteur mais le format du canal de sortie
courant (voir la fonction select()) peut être spéci?é explicitement en stockant le nom du format dans la variable $˜.
Le calcul de l’en-tête est fait automatiquement : si il n’y a pas assez de place sur la page courante pour l’enregistrement formaté,
on passe à la page suivante en af?chant un format d’en-tête spécial puis on y écrit l’enregistrement formaté. Par défaut, le nom
du format d’en-tête spécial est le nom du descripteur auquel on ajoute "_TOP" mais il peut être dynamiquement modi?é en
affectant le nom du format voulu à la variable $ˆ lorsque le descripteur est sélectionné (par select()). Le nombre de lignes
restant dans la page courante est donné par la variable $- qui peut être mise à 0 pour forcer le passage à la page suivante.
Si DESCRIPTEUR n’est pas spéci?é, le sortie se fait sur le canal de sortie courant qui, au début, est STDOUT mais qui peut
être changé par l’opérateur select(). Si le DESCRIPTEUR est une expression EXPR alors l’expression est évaluée et la
chaîne résultante est utilisé comme nom du descripteur à utiliser. Pour en savoir plus sur les formats, voir le manuel perlform.
Notez que write n’est PAS le contraire de read(). Malheureusement.
y///
L’opérateur de translittération. Identique à tr///. Voir le manuel perlop.
7.2
VERSION FRANÇAISE
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.0. Pour en savoir plus concernant ces traductions,
consultez ;.
7.3
TRADUCTION
Traduction initiale : Paul Gaborit <>, Jean-Pascal Peltier <>.
Mise à jour en 5.6.0 : Paul Gaborit <>.
7.4
RELECTURE
Personne pour l’instant.
135

Chapitre 8
perldsc – Livre de Cuisine des Structures de
Données de Perl

Livre de Cuisine des Structures de Données de Perl
8.1
DESCRIPTION
La seule caractéristique manquant cruellement au langage de programmation Perl avant sa version 5.0 était les structures de données
complexes. Même sans support direct par le langage, certains programmeurs vaillants parvinrent à les émuler, mais c’était un dur
travail, à déconseiller aux âmes sensibles. Vous pouviez occasionnellement vous en sortir avec la notation $m{$AoA,$b} empruntée à
awk dans laquelle les clés sont en fait plutôt une seule chaîne concaténée "$AoA$b", mais leurs parcours et leurs tris étaient dif?ciles.
Des programmeurs un peu plus désespérés ont même directement bitouillé la table de symboles interne de Perl, une stratégie qui
s’est montrée dure à développer et à maintenir - c’est le moins que l’on puisse dire.
La version 5.0 de Perl nous laisse disposer de structures de données complexes. Vous pouvez maintenant écrire quelque chose comme
ceci pour obtenir d’un seul coup un tableau à trois dimensions !
for $x (1 .. 10) {
for $y (1 .. 10) {
for $z (1 .. 10) {
$AoA[$x][$y][$z] =
$x ** $y + $z;
}
}
}
À première vue cette construction apparaît simple, mais elle est en fait beaucoup plus compliquée qu’elle ne le laisse paraître !
Comment est-ce que vous l’imprimez ? Pourquoi ne pouvez-vous pas juste dire print @AoA? Comment la triez-vous ? Comment
pouvez-vous la passer à une fonction ou en récupérer une depuis une fonction ? Est-ce un objet ? Pouvez-vous la sauver sur disque
pour la relire plus tard ? Comment accédez-vous à des lignes ou des colonnes entières de cette matrice ? Est-ce que toutes les valeurs
doivent être numériques ?
Comme vous le voyez, il est assez facile d’être déconcerté. Ces dif?cultés viennent, pour une petite partie, de l’implémentation basée
sur les références, mais pour l’essentiel, du manque de documentation existant disposant d’exemples destinés au débutant.
Ce document est conçu pour traiter, en détails mais de façon compréhensible toute une panoplie de structures de données que vous
pourriez être amené à développer. Il devrait aussi servir de livre de cuisine donnant des exemples. De cette façon, lorsque vous avez
besoin de créer l’une de ces structures de données complexes, vous pouvez simplement piquer, chaparder ou dérober un exemple de
ce guide.
Jetons un oeil en détails à chacune de ces constructions possibles. Il existe des sections séparées pour chacun des cas suivants :
– tableaux de tableaux
– hachages de tableaux
– tableaux de hachages
– hachages de hachages
– constructions plus élaborées
Mais pour le moment, jetons un oeil aux problèmes communs à tous ces types de structures de données.
136

8.2. RÉFÉRENCES
perldsc
8.2
RÉFÉRENCES
La chose la plus importante à comprendre au sujet de toutes les structures de données en Perl - y compris les tableaux multidimen-
sionnels - est que même s’ils peuvent paraître différents, les @TABLEAUx et les %HACHAGEs en Perl sont tous unidimensionnels en
interne. Ils ne peuvent contenir que des valeurs scalaires (c’est-à-dire une chaîne, un nombre ou une référence). Ils ne peuvent pas
contenir directement d’autres tableaux ou hachages, mais ils contiennent à la place des références à des tableaux ou des hachages.
Vous ne pouvez pas utiliser une référence à un tableau ou à un hachage exactement de la même manière que vous le feriez d’un
vrai tableau ou d’un vrai hachage. Pour les programmeurs C ou C++, peu habitués à distinguer les tableaux et les pointeurs vers des
tableaux, ceci peut être déconcertant. Si c’est le cas, pensez-y simplement comme à la différence entre une structure et un pointeur
vers une structure.
Vous pouvez (et devriez) en lire plus au sujet des références dans la page de manuel perlref(1). Brièvement, les références ressemblent
assez à des pointeurs sachant vers quoi ils pointent (les objets sont aussi une sorte de référence, mais nous n’en aurons pas besoin
pour le moment). Ceci signi?e que lorsque vous avez quelque chose qui vous semble être un accès à un tableau ou à un hachage à
deux dimensions ou plus, ce qui se passe réellement est que le type de base est seulement une entité unidimensionelle qui contient
des références vers le niveau suivant. Vous pouvez juste l’utiliser comme si c’était une entité à deux dimensions. C’est aussi en fait
la façon dont fonctionnent presque tous les tableaux multidimensionnels en C.
$array[7][12]
# tableau de tableaux
$array[7]{string}
# tableau de hachages
$hash{string}[7]
# hachage de tableaux
$hash{string}{’another string’}
# hachage de hachages
Maintenant, puisque le niveau supérieur ne contient que des références, si vous essayez d’imprimer votre tableau avec une simple
fonction print(), vous obtiendrez quelque chose qui n’est pas très joli, comme ceci :
@AoA = ( [2, 3], [4, 5, 7], [0] );
print $AoA[1][2];
7
print @AoA;
ARRAY(0x83c38)ARRAY(0x8b194)ARRAY(0x8b1d0)
C’est parce que Perl ne déréférence (presque) jamais implicitement vos variables. Si vous voulez atteindre la chose à laquelle se
réfère une référence, alors vous devez le faire vous-même soit en utilisant des pré?xes d’indication de typage, comme ${$blah},
@{$blah}, @{$blah[$i]}, soit des ?èches de pointage post?xes, comme $a->[3], $h->{fred}, ou même $ob->method()->[3].
8.3
ERREURS COURANTES
Les deux erreurs les plus communes faites dans l’affectation d’une donnée de type tableau de tableaux est soit l’affectation du nombre
d’éléments du tableau, (NdT : au lieu du tableau lui-même bien sûr :), soit l’affectation répétée d’une même référence mémoire. Voici
le cas où vous obtenez juste le nombre d’éléments au lieu d’un tableau imbriqué :
for $i (1..10) {
@list = somefunc($i);
$AoA[$i] = @list;
# FAUX !
}
C’est le cas simple où l’on affecte un tableau à un scalaire et où l’on obtient le nombre de ses éléments. Si c’est vraiment bien ce
que vous désirez, alors vous pourriez être un poil plus explicite à ce sujet, comme ceci :
for $i (1..10) {
@array = somefunc($i);
$counts[$i] = scalar @array;
}
Voici le cas où vous vous référez encore et encore au même emplacement mémoire :
for $i (1..10) {
@array = somefunc($i);
$AoA[$i] = \@array;
# FAUX !
}
137

8.3. ERREURS COURANTES
perldsc
Allons bon, quel est le gros problème ? Cela semble bon, n’est-ce pas ? Après tout, je viens de vous dire que vous aviez besoin d’un
tableau de références, alors ?ûte, vous m’en avez créé un !
Malheureusement, bien que cela soit vrai, cela ne marche pas. Toutes les références dans @AoA se réfère au même endroit, et elles
contiendront toutes par conséquent ce qui se trouvait en dernier dans @array ! Le problème est similaire à celui du programme C
suivant :
#include <pwd.h>
main() {
struct passwd *getpwnam(), *rp, *dp;
rp = getpwnam("root");
dp = getpwnam("daemon");
printf("daemon name is %s\nroot name is %s\n",
dp->pw_name, rp->pw_name);
}
Ce qui af?chera
daemon name is daemon
root name is daemon
Le problème est que rp et dp sont des pointeurs vers le même emplacement en mémoire ! En C, vous devez utiliser malloc() pour
vous réserver de la mémoire. En Perl, vous devez utiliser à la place le constructeur de tableau [] ou le constructeur de hachages {}.
Voici la bonne façon de procéder :
for $i (1..10) {
@array = somefunc($i);
$AoA[$i] = [ @array ];
}
Les crochets créent une référence à un nouveau tableau avec une copie de ce qui se trouve dans @array au moment de l’affectation.
C’est ce que vous désiriez.
Notez que ceci produira quelque chose de similaire, mais c’est bien plus dur à lire :
for $i (1..10) {
@array = 0 .. $i;
@{$AoA[$i]} = @array;
}
Est-ce la même chose ? Eh bien, peut-être que oui, peut-être que non. La différence subtile est que lorsque vous affectez quelque
chose entre crochets, vous êtes sûr que ce sera toujours une nouvelle référence contenant une nouvelle copie des données. Ça ne se
passera pas forcément comme ça avec le déréférencement @{$AoA[$i]}} du côté gauche de l’affectation. Tout dépend si $AoA[$i]
était pour commencer indé?ni, ou s’il contenait déjà une référence. Si vous aviez déjà peuplé @AoA avec des références, comme
dans
$AoA[3] = \@another_array;
alors l’affectation avec l’indirection du côté gauche utiliserait la référence existante déjà présente :
@{$AoA[3]} = @array;
Bien sûr, ceci aurait l’effet "intéressant" de démolir @another_list (Avez-vous déjà remarqué que lorsqu’un programmeur dit que
quelque chose est "intéressant", au lieu de dire "intrigant", alors ça signi?e que c’est "ennuyeux", "dif?cile", ou les deux ? :-).
Souvenez-vous donc juste de toujours utiliser le constructeur de tableau ou de hachage [] ou {}, et tout ira bien pour vous, même si
ce n’est pas la solution optimale.
De façon surprenante, la construction suivante qui a l’air dangereuse marchera en fait très bien :
for $i (1..10) {
my @array = somefunc($i);
$AoA[$i] = \@array;
}
138

8.4. AVERTISSEMENT SUR LA PRÉCÉDENCE
perldsc
C’est parce que my() est plus une expression utilisée lors de l’exécution qu’une déclaration de compilation en elle-même. Cela
signi?e que la variable my() est recréée de zéro chaque fois que l’on traverse la boucle. Donc même si on a l’impression que
vous stockez la même référence de variable à chaque fois, ce n’est pas le cas ! C’est une distinction subtile qui peut produire un
code plus ef?cace au risque de tromper tous les programmeurs sauf les plus expérimentés. Je déconseille donc habituellement de
l’enseigner aux débutants. En fait, sauf pour passer des arguments à des fonctions, j’aime rarement voir l’opérateur "donne-moi-une-
référence" (backslash) utilisé dans du code. À la place, je conseille aux débutants (et à la plupart d’entre nous) d’essayer d’utiliser
les constructeurs bien plus compréhensibles [] et {} au lieu de se reposer sur une astuce lexicale (ou dynamique) et un comptage de
référence caché pour faire ce qu’il faut en coulisses.
En résumé :
$AoA[$i] = [ @array ];
# habituellement mieux
$AoA[$i] = \@array;
# perilleux ; tableau declare
# avec my() ? Comment ?
@{ $AoA[$i] } = @array;
# bien trop astucieux pour la plupart
# des programmeurs
8.4
AVERTISSEMENT SUR LA PRÉCÉDENCE
En parlant de choses comme @{$AoA[$i]}, les expressions suivantes sont en fait équivalentes :
$aref->[2][2]
# clair
$$aref[2][2]
# troublant
C’est dû aux règles de précédence de Perl qui rend les cinq pré?xes déréférenceurs (qui ont l’air de jurons : $ @ * % &) plus
prioritaires que les accolades et les crochets d’indiçage post?xes ! Ceci sera sans doute un grand choc pour le programmeur C ou
C++, qui est habitué à utiliser *a[i] pour indiquer ce qui est pointé par le ième élément de a. C’est-à-dire qu’ils prennent d’abord
l’indice, et ensuite seulement déréférencent la structure à cet indice. C’est bien en C, mais nous ne parlons pas de C.
La construction apparemment équivalente en Perl, $$aref[$i] commence par déréférencer $aref, le faisant prendre $aref comme
une référence à un tableau, et puis déréférence cela, et ?nalement vous donne la valeur du ième élément du tableau pointé par $AoA.
Si vous vouliez la notion équivalente en C, vous devriez écrire ${$AoA[$i]} pour forcer l’évaluation de $AoA[$i] avant le premier
déréférenceur $.
8.5
POURQUOI VOUS DEVRIEZ TOUJOURS UTILISER use strict
Ce n’est pas aussi effrayant que ça en a l’air, détendez-vous. Perl possède un certain nombre de caractéristiques qui vont vous aider
à éviter les pièges les plus communs. La meilleure façon de ne pas être troublé est de commencer les programmes ainsi :
#!/usr/bin/perl -w
use strict;
De cette façon, vous serez forcé de déclarer toutes vos variables avec my() et aussi d’interdire tout "déréférencement symbolique"
accidentel. Par conséquent, si vous faites ceci :
my $aref = [
[ "fred", "barney", "pebbles", "bambam", "dino", ],
[ "homer", "bart", "marge", "maggie", ],
[ "george", "jane", "elroy", "judy", ],
];
print $aref[2][2];
Le compilateur marquera immédiatement ceci comme une erreur lors de la compilation, car vous accédez accidentellement à @aref
qui est une variable non déclarée, et il vous proposerait d’écrire à la place :
print $aref->[2][2]
139

8.6. DÉBOGAGE
perldsc
8.6
DÉBOGAGE
Avant la version 5.002, le débogueur standard de Perl ne faisait pas un très bon travail lorsqu’il devait imprimer des structures de
données complexes. Avec la 5.002 et les suivantes, le débogueur inclut plusieurs nouvelles caractéristiques, dont une édition de la
ligne de commande ainsi que la commande x pour af?cher les structures de données complexes. Par exemple, voici la sortie du
débogueur avec l’affectation à $AoA ci-dessus :
DB<1> x $AoA
$AoA = ARRAY(0x13b5a0)
0
ARRAY(0x1f0a24)
0
’fred’
1
’barney’
2
’pebbles’
3
’bambam’
4
’dino’
1
ARRAY(0x13b558)
0
’homer’
1
’bart’
2
’marge’
3
’maggie’
2
ARRAY(0x13b540)
0
’george’
1
’jane’
2
’elroy’
3
’judy’
8.7
EXEMPLES DE CODE
Présentés avec peu de commentaires (ils auront leurs propres pages de manuel un jour), voici de courts exemples de code illustrant
l’accès à divers types de structures de données.
8.8
TABLEAUX DE TABLEAUX
8.8.1
Déclaration d’un TABLEAU DE TABLEAUX
@AoA = (
[ "fred", "barney" ],
[ "george", "jane", "elroy" ],
[ "homer", "marge", "bart" ],
);
8.8.2
Génération d’un TABLEAU DE TABLEAUX
# lecture dans un fichier
while ( <> ) {
push @AoA, [ split ];
}
# appel d’une function
for $i ( 1 .. 10 ) {
$AoA[$i] = [ somefunc($i) ];
}
# utilisation de variables temporaires
for $i ( 1 .. 10 ) {
@tmp = somefunc($i);
$AoA[$i] = [ @tmp ];
}
# ajout dans une rangée existante
push @{ $AoA[0] }, "wilma", "betty";
140

8.9. HACHAGE DE TABLEAUX
perldsc
8.8.3
Accès et Af?chage d’un TABLEAU DE TABLEAUX
# un element
$AoA[0][0] = "Fred";
# un autre element
$AoA[1][1] =~ s/(\w)/\u$1/;
# affiche le tout avec des refs
for $aref ( @AoA ) {
print "\t [ @$aref ],\n";
}
# affiche le tout avec des indices
for $i ( 0 .. $#AoA ) {
print "\t [ @{$AoA[$i]} ],\n";
}
# affiche tous les elements un par un
for $i ( 0 .. $#AoA ) {
for $j ( 0 .. $#{ $AoA[$i] } ) {
print "elt $i $j is $AoA[$i][$j]\n";
}
}
8.9
HACHAGE DE TABLEAUX
8.9.1
Déclaration d’un HACHAGE DE TABLEAUX
%HoA = (
flintstones
=> [ "fred", "barney" ],
jetsons
=> [ "george", "jane", "elroy" ],
simpsons
=> [ "homer", "marge", "bart" ],
);
8.9.2
Génération d’un HACHAGE DE TABLEAUX
# lecture dans un fichier
# flintstones: fred barney wilma dino
while ( <> ) {
next unless s/^(.*?):\s*//;
$HoA{$1} = [ split ];
}
# lecture dans un fichier avec plus de variables temporaires
# flintstones: fred barney wilma dino
while ( $line = <> ) {
($who, $rest) = split /:\s*/, $line, 2;
@fields = split ’ ’, $rest;
$HoA{$who} = [ @fields ];
}
# appel d’une fonction qui retourne une liste
for $group ( "simpsons", "jetsons", "flintstones" ) {
$HoA{$group} = [ get_family($group) ];
}
# idem, mais en utilisant des variables temporaires
for $group ( "simpsons", "jetsons", "flintstones" ) {
@members = get_family($group);
$HoA{$group} = [ @members ];
}
# ajout de nouveaux membres a une famille existante
push @{ $HoA{"flintstones"} }, "wilma", "betty";
141

8.10. TABLEAUX DE HACHAGES
perldsc
8.9.3
Accès et Af?chage d’un HACHAGE DE TABLEAUX
# un element
$HoA{flintstones}[0] = "Fred";
# un autre element
$HoA{simpsons}[1] =~ s/(\w)/\u$1/;
# affichage du tout
foreach $family ( keys %HoA ) {
print "$family: @{ $HoA{$family} }\n"
}
# affichage du tout avec des indices
foreach $family ( keys %HoA ) {
print "family: ";
foreach $i ( 0 .. $#{ $HoA{$family} } ) {
print " $i = $HoA{$family}[$i]";
}
print "\n";
}
# affichage du tout trie par le nombre de membres
foreach $family ( sort { @{$HoA{$b}} <=> @{$HoA{$a}} } keys %HoA ) {
print "$family: @{ $HoA{$family} }\n"
}
# affichage du tout trie par le nombre de membres et le nom
foreach $family ( sort {
@{$HoA{$b}} <=> @{$HoA{$a}}
||
$a cmp $b
} keys %HoA )
{
print "$family: ", join(", ", sort @{ $HoA{$family} }), "\n";
}
8.10
TABLEAUX DE HACHAGES
8.10.1
Déclaration d’un TABLEAU DE HACHAGES
@AoH = (
{
Lead
=> "fred",
Friend
=> "barney",
},
{
Lead
=> "george",
Wife
=> "jane",
Son
=> "elroy",
},
{
Lead
=> "homer",
Wife
=> "marge",
Son
=> "bart",
}
);
142

8.10. TABLEAUX DE HACHAGES
perldsc
8.10.2
Génération d’un TABLEAU DE HACHAGES
# lecture dans un fichier
# format : LEAD=fred FRIEND=barney
while ( <> ) {
$rec = {};
for $field ( split ) {
($key, $value) = split /=/, $field;
$rec->{$key} = $value;
}
push @AoH, $rec;
}
# lecture dans un fichier sans variable temporaire
# format: LEAD=fred FRIEND=barney
while ( <> ) {
push @AoH, { split /[\s+=]/ };
}
# appel d’une fonction qui retourne une liste clé/valeur, comme
# "lead","fred","daughter","pebbles"
while ( %fields = getnextpairset() ) {
push @AoH, { %fields };
}
# idem, mais sans variables temporaires
while (<>) {
push @AoH, { parsepairs($_) };
}
# ajout d’un couple clé/valeur à un element
$AoH[0]{pet} = "dino";
$AoH[2]{pet} = "santa’s little helper";
8.10.3
Accès et Af?chage d’un TABLEAU DE HACHAGES
# un element
$AoH[0]{lead} = "fred";
# un autre element
$AoH[1]{lead} =~ s/(\w)/\u$1/;
# affichage du tout avec des refs
for $href ( @AoH ) {
print "{ ";
for $role ( keys %$href ) {
print "$role=$href->{$role} ";
}
print "}\n";
}
# affichage du tout avec des indices
for $i ( 0 .. $#AoH ) {
print "$i is { ";
for $role ( keys %{ $AoH[$i] } ) {
print "$role=$AoH[$i]{$role} ";
}
print "}\n";
}
143

8.11. HACHAGES DE HACHAGES
perldsc
# affichage du tout element par element
for $i ( 0 .. $#AoH ) {
for $role ( keys %{ $AoH[$i] } ) {
print "elt $i $role is $AoH[$i]{$role}\n";
}
}
8.11
HACHAGES DE HACHAGES
8.11.1
Déclaration d’un HACHAGE DE HACHAGES
%HoH = (
flintstones => {
lead
=> "fred",
pal
=> "barney",
},
jetsons
=> {
lead
=> "george",
wife
=> "jane",
"his boy" => "elroy",
},
simpsons
=> {
lead
=> "homer",
wife
=> "marge",
kid
=> "bart",
},
);
8.11.2
Génération d’un HACHAGE DE HACHAGES
# lecture dans un fichier
# flintstones: lead=fred pal=barney wife=wilma pet=dino
while ( <> ) {
next unless s/^(.*?):\s*//;
$who = $1;
for $field ( split ) {
($key, $value) = split /=/, $field;
$HoH{$who}{$key} = $value;
}
# lecture dans un fichier, encore plus de variables temporaires
while ( <> ) {
next unless s/^(.*?):\s*//;
$who = $1;
$rec = {};
$HoH{$who} = $rec;
for $field ( split ) {
($key, $value) = split /=/, $field;
$rec->{$key} = $value;
}
}
# appel d’une fonction qui retourne un hachage clé/valeur
for $group ( "simpsons", "jetsons", "flintstones" ) {
$HoH{$group} = { get_family($group) };
}
144

8.11. HACHAGES DE HACHAGES
perldsc
# idem, mais en utilisant des variables temporaires
for $group ( "simpsons", "jetsons", "flintstones" ) {
%members = get_family($group);
$HoH{$group} = { %members };
}
# ajout de nouveaux membres a une famille existante
%new_folks = (
wife => "wilma",
pet
=> "dino",
);
for $what (keys %new_folks) {
$HoH{flintstones}{$what} = $new_folks{$what};
}
8.11.3
Accès et Af?chage d’un HACHAGE DE HACHAGES
# un element
$HoH{flintstones}{wife} = "wilma";
# un autre element
$HoH{simpsons}{lead} =~ s/(\w)/\u$1/;
# affichage du tout
foreach $family ( keys %HoH ) {
print "$family: { ";
for $role ( keys %{ $HoH{$family} } ) {
print "$role=$HoH{$family}{$role} ";
}
print "}\n";
}
# affichage du tout un peu trie
foreach $family ( sort keys %HoH ) {
print "$family: { ";
for $role ( sort keys %{ $HoH{$family} } ) {
print "$role=$HoH{$family}{$role} ";
}
print "}\n";
}
# affichage du tout trie par le nombre de membres
foreach $family ( sort { keys %{$HoH{$b}} <=> keys %{$HoH{$a}} } keys %HoH ) {
print "$family: { ";
for $role ( sort keys %{ $HoH{$family} } ) {
print "$role=$HoH{$family}{$role} ";
}
print "}\n";
}
# etablissement d’un ordre de tri (rang) pour chaque role
$i = 0;
for ( qw(lead wife son daughter pal pet) ) { $rank{$_} = ++$i }
# maintenant affiche le tout trie par le nombre de membres
foreach $family ( sort { keys %{ $HoH{$b} } <=> keys %{ $HoH{$a} } } keys %HoH ) {
print "$family: { ";
# et affichage selon l’ordre de tri (rang)
for $role ( sort { $rank{$a} <=> $rank{$b} }
keys %{ $HoH{$family} } ) {
print "$role=$HoH{$family}{$role} ";
}
print "}\n";
}
145

8.12. ENREGISTREMENTS PLUS ÉLABORÉS
perldsc
8.12
ENREGISTREMENTS PLUS ÉLABORÉS
8.12.1
Déclaration d’ENREGISTREMENTS PLUS ÉLABORÉS
Voici un exemple montrant comment créer et utiliser un enregistrement dont les champs sont de types différents :
$rec = {
TEXT
=> $string,
SEQUENCE
=> [ @old_values ],
LOOKUP
=> { %some_table },
THATCODE
=> \&some_function,
THISCODE
=> sub { $_[0] ** $_[1] },
HANDLE
=> \*STDOUT,
};
print $rec->{TEXT};
print $rec->{SEQUENCE}[0];
$last = pop @ { $rec->{SEQUENCE} };
print $rec->{LOOKUP}{"key"};
($first_k, $first_v) = each %{ $rec->{LOOKUP} };
$answer = $rec->{THATCODE}->($arg);
$answer = $rec->{THISCODE}->($arg1, $arg2);
# attention aux accolades de bloc supplementaires sur la ref fh
print { $rec->{HANDLE} } "a string\n";
use FileHandle;
$rec->{HANDLE}->autoflush(1);
$rec->{HANDLE}->print(" a string\n");
8.12.2
Déclaration d’un HACHAGE D’ENREGISTREMENTS COMPLEXES
%TV = (
flintstones => {
series
=> "flintstones",
nights
=> [ qw(monday thursday friday) ],
members
=> [
{ name => "fred",
role => "lead", age
=> 36, },
{ name => "wilma",
role => "wife", age
=> 31, },
{ name => "pebbles", role => "kid",
age
=>
4, },
],
},
jetsons
=> {
series
=> "jetsons",
nights
=> [ qw(wednesday saturday) ],
members
=> [
{ name => "george",
role => "lead", age
=> 41, },
{ name => "jane",
role => "wife", age
=> 39, },
{ name => "elroy",
role => "kid",
age
=>
9, },
],
},
simpsons
=> {
series
=> "simpsons",
nights
=> [ qw(monday) ],
members
=> [
{ name => "homer", role => "lead", age
=> 34, },
{ name => "marge", role => "wife", age => 37, },
{ name => "bart",
role => "kid",
age
=>
11, },
],
},
);
146

8.12. ENREGISTREMENTS PLUS ÉLABORÉS
perldsc
8.12.3
Génération d’un HACHAGE D’ENREGISTREMENTS COMPLEXES
# lecture d’un fichier
# c’est plus facile a faire quand on dispose du fichier lui-meme
# dans le format de donnees brut explicite ci-dessus. perl analyse
# joyeusement les structures de donnees complexes si elles sont
# declarees comme des donnees, il est donc parfois plus facile de
# faire ceci
# voici un assemblage morceau par morceau
$rec = {};
$rec->{series} = "flintstones";
$rec->{nights} = [ find_days() ];
@members = ();
# on presume que ce fichier a la syntaxe champ=valeur
while (<>) {
%fields = split /[\s=]+/;
push @members, { %fields };
}
$rec->{members} = [ @members ];
# maintenant on se rappelle du tout
$TV{ $rec->{series} } = $rec;
###########################################################
# maintenant, vous pourriez vouloir creer des champs
# supplementaires interessants incluant des pointeurs vers
# l’interieur de cette meme structure de donnees pour que
# si l’on en change un morceau, il se retrouve change partout
# ailleurs, comme par exemple un champ {kids} (enfants, NDT)
# qui serait une reference vers un tableau des enregistrements
# des enfants, sans avoir d’enregistrements dupliques et donc
# des soucis de mise a jour.
###########################################################
foreach $family (keys %TV) {
$rec = $TV{$family}; # pointeur temporaire
@kids = ();
for $person ( @{ $rec->{members} } ) {
if ($person->{role} =~ /kid|son|daughter/) {
push @kids, $person;
}
}
# SOUVENEZ-VOUS : $rec et $TV{$family} pointent sur les memes donnees !!
$rec->{kids} = [ @kids ];
}
# vous avez copie le tableau, mais le tableau lui-meme contient des
# pointeurs vers des objets qui n’ont pas été copiés. Cela veut
# dire que si vous vieillissez bart en faisant
$TV{simpsons}{kids}[0]{age}++;
# alors ça changerait aussi
print $TV{simpsons}{members}[2]{age};
# car $TV{simpsons}{kids}[0] et $TV{simpsons}{members}[2]
# pointent tous deux vers la meme table de hachage anonyme sous-jacente
# imprime le tout
foreach $family ( keys %TV ) {
print "the $family";
147

8.13. LIENS AVEC LES BASES DE DONNÉES
perldsc
print " is on during @{ $TV{$family}{nights} }\n";
print "its members are:\n";
for $who ( @{ $TV{$family}{members} } ) {
print " $who->{name} ($who->{role}), age $who->{age}\n";
}
print "it turns out that $TV{$family}{lead} has ";
print scalar ( @{ $TV{$family}{kids} } ), " kids named ";
print join (", ", map { $_->{name} } @{ $TV{$family}{kids} } );
print "\n";
}
8.13
Liens avec les Bases de Données
Il n’est pas possible de lier facilement une structure de données multiniveaux (tel qu’un hachage de hachages) à un ?chier de base
de données (?chier dbm). Le premier problème est que tous ces ?chiers, à l’exception des GBM et des DB de Berkeley, ont des
limitations de taille, mais il y a d’autres problèmes dûs la manière dont les références sont représentées sur le disque. Il existe un
module expérimental, le module MLDM, qui essaye de combler partiellement ce besoin. Pour obtenir le code source du module
MLDBM allez voir sur le site CPAN le plus proche comme décrit dans le manuel perlmodlib.
8.14
VOIR AUSSI
perlref(1), perllol(1), perldata(1), perlobj(1)
8.15
AUTHOR
Tom Christiansen <>
Dernière mise à jour : Wed Oct 23 04:57:50 MET DST 1996
8.16
VERSION FRANÇAISE
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.1. Pour en savoir plus concernant ces traductions,
consultez ;.
8.17
TRADUCTION
Roland Trique <>
8.18
RELECTURE
Pascal Ethvignot <> Etienne Gauthier <>
148

Chapitre 9
perlpod – plain old documentation ("bonne
vieille documentation")

Plain old documentation ("bonne vieille documentation")
9.1
DESCRIPTION
Un traducteur pod-vers-n’importe quoi lit un ?chier pod paragraphe par paragraphe, et le traduit dans le format de sortie approprié.
Il existe trois genres de paragraphes :
le titre mot pour mot|/"Paragraphe Mot pour Mot" dans ce document, le titre de commande|/"Paragraphe de Commande" dans ce
document, et le titre texte ordinaire|/"Bloc de Texte Ordinaire" dans ce document.
9.1.1
Paragraphe Mot pour Mot
Un paragraphe mot pout mot (verbatim) est distingué par son indentation (c’est-à-dire qu’il commence par une espace ou une tabula-
tion). Il devrait être reproduit exactement, avec les tabulations supposées être sur 8 colonnes. Il n’y a pas de séquences d’échappement
spéciales pour le formatage, vous ne pouvez donc pas mettre en italique ni quoi que ce soit. Un \ veut dire \, et rien d’autre.
9.1.2
Paragraphe de Commande
Tous les paragraphes de commande commencent par "=", suivi par un identi?cateur, suivi par un texte arbitraire que la commande
peut utilise de la façon qui lui plaît. Les commandes reconnues actuellement sont
=head1 titre
=head2 titre
=item texte
=over N
=back
=cut
=pod
=for X
=begin X
=end X
=pod
=cut
La directive "=pod" ne fait rien d’autre que dire au compilateur de suspendre son analyse du code jusqu’au prochain "=cut".
C’est utile pour ajouter un nouveau paragraphe à la doc si vous mélangez beaucoup le code et le pod.
=head1
=head2
Head1 et head2 produisent des titres de premier et de second niveau, avec le texte situé dans le même paragraphe que la
directive "=headn" formant la description du titre.
149

9.1. DESCRIPTION
perlpod
=over
=back
=item
Item, over, et back ont besoin d’un peu plus d’explications : "=over" débute une section spéci?quement en vue de la créa-
tion d’une liste utilisant des commandes "=item". Utilisez "=back" à la ?n de votre liste pour la terminer. Vous voudrez
probablement donner "4" comme nombre à "=over", car certains formateurs utiliseront ceci pour l’indentation. Ceci devrait
probablement être une valeur par défaut. Notez aussi qu’il y a des règles de base dans l’usage de =item : ne les utilisez pas
hors d’un bloc =over/=back, utilisez-en au moins un à l’intérieur d’un bloc =over/=back, vous n’êtes pas _obligé_ d’inclure
le =back si la liste continue jusqu’à la ?n du document, et, ceci étant peut-être le plus important, gardez les items cohérents :
utilisez soit "=item *" pour tous, pour produire des puces, ou bien utilisez "=item 1.", "=item 2.", etc., pour produire des
listes numérotées, ou bien utilisez "=item foo", "=item bar", etc., i.e., des choses qui n’ont rien à voir avec des puces ou des
numéros. Si vous commencez avec des puces ou des numéros, gardez-les, car beaucoup de formateurs utiliseront le type du
premier "=item" pour décider comment formater toute la liste.
=for
=begin
=end
For, begin, et end vous permettent d’inclure des sections qui ne sont pas interprétées comme du texte pod, mais passées
directement à des formateurs particuliers. Un formateur qui peut utiliser ce format traitera la section, qui sera complètement
ignorée sinon. La directive "=for" spéci?e que la totalité du prochain paragraphe est dans le format indiqué par le premier mot
après le "=for", comme ceci :
=for html <br>
<p> This is a raw HTML paragraph </p>
La paire de commandes "=begin" et "=end" fonctionne de façon très similaires à "=for", mais au lieu de n’accepter seulement
qu’un seul paragraphe, tout le texte depuis le "=begin" jusqu’au paragraphe ayant un "=end" assorti est traité comme d’un
format particulier.
Voici des exemples de l’utilisation de ceci :
=begin html
<br>Figure 1.<IMG SRC=""><br>
=end html
=begin text
---------------
|
foo
|
|
bar
|
---------------
^^^^ Figure 1. ^^^^
=end text
Certains noms de format que les formateurs sont connus pour accepter actuellement incluent "roff", "man", "latex", "tex",
"text", et "html" (certains formateurs traiteront certains de ceux-ci comme des synonymes).
Et n’oubliez pas, en utilisant toute commande, que son effet dure jusqu’à la ?n du paragraphe, pas de la ligne. D’où dans les
exemples ci-dessus, les lignes vides que vous pouvez voir après chaque commande pour terminer son paragraphe.
Des exemples de listes incluent :
=over 4
=item *
First item
=item *
Second item
=back
=over 4
150

9.1. DESCRIPTION
perlpod
=item Foo()
Description of Foo function
=item Bar()
Description of Bar function
=back
9.1.3
Bloc de Texte Ordinaire
Il sera plein, et peut-être même justi?é. Certaines séquences internes sont reconnues à la fois ici et dans les commandes :
I<texte>
Texte en italique, utilisé pour l’accentuation ou les variables
B<texte>
Texte en gras, utilisé pour les options et les programmes
S<texte>
Le texte contient des espaces insécables
C<code>
Code littéral
L<nom>
Un lien (référence croisée) vers nom
L<nom>
page de manuel
L<nom/ident>
élément dans la page de manuel
L<nom/"sec">
section dans une autre page de manuel
L<"sec">
section dans cette page de manuel
(les guillemets sont optionels)
L</"sec">
idem
la même chose que ci-dessus mais seul ’texte’ est utilisé comme sortie.
(Le Texte ne peut pas contenir les caractères ’/’ et ’|’,
et devrait contenir des ’<’ ou des ’>’ appariés)
L<texte|nom>
L<texte|nom/ident>
L<texte|nom/"sec">
L<texte|"sec">
L<texte|/"sec">
F<file>
Utilisé pour les noms de fichier
X<index>
Une entrée d’index
Z<>
Un caractère de largeur nulle
E<escape>
Un caractère nommé (très similaire aux séquences d’échappement HTML)
E<lt>
Un < litteral
E<gt>
Un > litteral
E<sol>
Un / litteral
E<verbar>
Un | litteral
(Ceux-ci sont optionnels sauf dans d’autres séquences internes
et quand ils sont précédés d’une lettre majuscule)
E<n>
Caractère numéro n (probablement en ASCII)
E<html>
Une entité HTML non numérique, comme
E<Agrave>
La plupart du temps, vous n’aurez besoin que d’un seul jeu de crochets pour délimiter le début et la ?n des séquences internes.
Toutefois vous voudrez parfois mettre un signe supérieur à dans une séquence. C’est particulièrement courant lorsqu’on utilise une
séquence pour fournir une fonte différente pour un petit bout de code. Comme pour toute chose en Perl, il y a plus d’une façon de le
faire. L’une d’elle est de simplement protéger le crochet fermant en utilisant une séquence E :
C<$a E<lt>=E<gt> $b>
Ce qui produira : "$a <=> $b"
Une méthode plus lisible, et peut-etre plus "simple", est d’utiliser une autre paire de délimiteurs qui n’ont pas besoin d’un ">" pour
leur protection. À partir de perl5.5.660, les crochets doublés ("«" et "»") peuvent etre utilisés si et seulement si des espaces suivent
immédiatement le crochet ouvrant et précèdent le crochet fermant ! 
Par exemple, ce qui suit fonctionnera :
C<< $a <=> $b >>
151

9.1. DESCRIPTION
perlpod
En fait, vous pouvez utiliser autant de crochets répétés que vous le désirez tant qu’il y en a autant dans les délimiteurs ouvrants et
fermants, et que vous vous assurez que l’espace suit immédiatement le dernier ’<’ du délimiteur ouvrant, et précède immédiatement
le premier ’>’ du délimiteur fermant. Ce qui suit fonctionnera donc aussi :
C<<< $a <=> $b >>>
C<<<< $a <=> $b >>>>
C’est actuellement supporté par pod2text (Pod::Text), pod2man (Pod::Man), et tout autre traducteur pod2xxx et Pod::Xxxx qui utilise
Pod::Parser version 1.093 ou supérieure.
9.1.4
Le Dessein
C’est cela. Le dessein est la simplicité, pas la puissance. Je voulais que les paragraphes aient l’air de paragraphes (format de bloc),
pour qu’ils ressortent visuellement, et pour que je puisse les faire passer facilement à travers fmt pour les reformater (c’est F7 dans
ma version de vi). Je voulais que le traducteur (et pas moi) s’inquiète de savoir si " ou ’ est une apostrophe ou un accent grave dans le
texte plein, et je voulais qu’il laisse les apostrophe tranquilles, nom d’une pipe, en mode mot pour mot, pour que je puisse l’aspirer
dans un programme qui marche, le décaler de 4 espaces, et l’imprimer, euh, mot pour mot. Et probablement dans une fonte à chasse
?xe.
En particulier, vous pouvez laisser des choses comme ceci mot pour mot dans votre texte :
Perl
FILEHANDLE
$variable
function()
manpage(3r)
Sans doute quelques commandes ou séquences supplémentaires auront besoin d’être ajoutées en cours de route, mais je m’en suis
étonnemment bien sorti avec juste celles-ci.
Notez que je ne proclame pas du tout que ceci est suf?sant pour produire un livre. J’essaye juste de faire une source commune à
l’épreuve des idiots pour nroff, TeX, et les autres langages de marquage, tels qu’ils sont utilisés pour la documentation en ligne. Des
traducteurs existent pour pod2man (ceci est pour nroff(1) et troff(1)), pod2textpod2htmlpod2latex, et pod2fm.
9.1.5
Incorporer du Pod dans les Modules Perl
Vous pouvez inclure de la documentation pod dans vos scripts Perl. Commencez votre documentation par une commande "=head1"
au début, et terminez-la par une commande "=cut". Perl ignorera le texte en pod. Voyez n’importe quel module de bibliothèque
fourni comme exemple. Si vous allez mettre votre pod à la ?n du ?chier, et si vous utilisez un __END__ ou un __DATA__ comme
marque de ?n, assurez-vous de mettre une ligne vide à cet endroit avant la première directive pod.
__END__
=head1 NAME
modern - I am a modern module
Si vous n’aviez pas eu cette ligne vide à cet endroit, alors les traducteurs ne l’auraient pas vu.
9.1.6
Pièges Courants de Pod
– Les traducteurs Pod requièrent habituellement que les paragraphes soient séparés par des lignes complètement vides. Si vous avez
une ligne apparemment vide contenant des espaces, Cela peut provoquer un formatage étrange.
– Les traducteurs ajouteront généralement des mots autour d’un lien L<>, de façon que L<foo(1)> devienne "the foo(1) manpage",
par exemple (voir pod2man pour des détails). Ainsi, vous ne devriez pas écrire de choses the L<foo> manpage, si vous voulez
que le document traduit se lise de façon sensée.
Si vous avez besoin du contrôle total du texte utilisé pour un lien dans la sortie, utilisez la forme L<show this text|foo> à la place.
– La commande podchecker est fournie pour rechercher les erreurs et les avertissements dans la syntaxe pod. Elle véri?e par
exemple les lignes complètement blanches dans les segments pod et les séquences d’échappement inconnues. Il est toujours
conseillé de faire passer votre pod dans un ou plusieurs traducteurs et de relire le résultat, ou de l’imprimer et de relire cela.
Certains des problèmes trouvés peuvent être des bugs dans le traducteur, que vous pourriez ou non désirer contourner.
152

9.2. VOIR AUSSI
perlpod
9.2
VOIR AUSSI
le manuel pod2man, le titre POD : Documentation Enfouie dans le manuel perlsyn, le manuel podchecker
9.3
AUTEUR
Larry Wall
9.4
VERSION FRANÇAISE
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.0. Pour en savoir plus concernant ces traductions,
consultez ;.
9.5
TRADUCTION
Roland Trique <>
9.6
RELECTURE
Personne pour l’instant.
153

Chapitre 10
perlstyle – Comment (bien) écrire du Perl
Comment (bien) écrire du Perl
10.1
DESCRIPTION
Chaque programmeur aura, bien entendu, ses propres préférences dans la manière d’écrire, mais voici quelques règles générales qui
rendront vos programmes plus faciles à lire, à comprendre et à mettre à jour.
La chose la plus importante est de toujours lancer vos programmes avec le paramètre -w. Si vous en avez vraiment besoin, vous avez
la possibilité de l’enlever explicitement pour des portions de vos programmes à l’aide du pragma use warnings ou de la variable
$ˆW. Vous devriez aussi toujours utiliser use strict ou au moins savoir pourquoi vous ne le faites pas. Les pragmas use sigtrap
et même use diagnostics pourrons s’avérer utiles.
Pour ce qui est de l’esthétique du code, la seule chose à laquelle Larry tienne vraiment, c’est que les accolades fermantes d’un BLOC
multiligne soient alignés avec le mot clé qui marque le début du bloc. Après ça, il a d’autres conseils qui ne sont pas aussi forts :
– Indentation de 4 colonnes.
– Les accolades ouvrantes sont sur la même ligne que le mot clé, si possible, sinon, qu’elles soient alignées avec lui.
– Un espace avant l’accolade ouvrante d’un BLOC multiligne.
– Un BLOC d’une ligne peut être mis sur la même ligne que le mot clé, y compris les accolades.
– Pas d’espace avant le point-virgule.
– Point-virgule omit dans les BLOCS d’une seule ligne.
– Des espaces autour autour des opérateurs.
– Des espaces autour d’un indice "complexe" (entre crochets).
– Des lignes vides entre les parties qui font des choses différentes.
– Des else bien visibles.
– Pas d’espace entre le nom de fonction et la parenthèse ouvrante.
– Un espace après chaque virgule.
– Couper Les lignes trop longues après un opérateur (sauf "and" et "or").
– Un espace après la dernière parenthèse fermante sur la ligne courante.
– Aligner les items correspondants verticalement.
– Omettre la ponctuation redondante tant que la lisibilité n’en est pas affectée.
Larry a ses propres raisons pour chacune de ces choses, mais il sait bien que tout le monde ne pense pas comme lui.
Voici quelques autres choses plus concrètes auxquelles il faut penser :
– Ce n’est pas parce que vous POUVEZ faire quelque chose d’une façon particulière que vous DEVEZ le faire de cette manière.
Perl a été conçu pour vous offrir plusieurs possibilités de faire une chose précise, alors, pensez à prendre la plus compréhensible.
Par exemple :
open(FOO,$foo) || die "J’arrive pas à ouvrir $foo: $!";
est mieux que :
die "J’arrive pas a ouvrir $foo: $!" unless open(FOO,$foo);
et ce, parce que la deuxième méthode ne met pas en avant l’instruction intéressante. D’un autre côté :
print "Début de l’analyse\n" if $verbose;
est mieux que :
$verbose && print "Début de l’analyse\n";
154

10.1. DESCRIPTION
perlstyle
car l’intérêt n’est pas de savoir si l’utilisateur a tapé -v ou non.
D’une manière similaire, ce n’est pas parce qu’un opérateur suppose des arguments par défaut qu’il faut que vous utilisiez ces
arguments. Les réglages par défaut sont faits pour les programmeurs systèmes paresseux qui écrivent un programme pour une
seule utilisation. Si vous voulez que votre programme soit lisible, mettez les arguments.
Dans le même ordre d’idée, ce n’est pas parce que les parenthèses peuvent être omises qu’il ne faut pas en mettre :
return print reverse sort num values %array;
return print(reverse(sort num (values(%array))));
Quand vous avez un doute, mettez des parenthèses. Au moins, ça permettra aux pauvres gars de s’en remettre à la touche % sous
vi.
Même si vous êtes sûr de vous, pensez à la santé mentale de la personne qui aura à mettre à jour le code après vous et qui mettra
très certainement les parenthèses au mauvais endroit.
– Ne faites pas de contorsions impossibles pour réussir à sortir d’une boucle, Perl fournis l’opérateur last qui vous permet de sortir.
Faites le juste dépasser pour le rendre plus visible ("outdent" en anglais).
LINE:
for (;;) {
instructions;
last LINE if $truc;
next LINE if /^#/;
instructions;
}
N’ayez pas peur d’utiliser des labels de boucle. Ils sont là pour rendre le code plus lisible autant que pour permettre de sauter
plusieurs niveaux de boucles. Référez vous à l’exemple précédent.
– Évitez d’utiliser grep() (ou map()) ou des ‘backticks‘ dans un contexte vide, c’est-à-dire, quand vous ne récupérez pas les valeurs
qu’elles retournent. Ces fonctions retournent toujours des valeurs alors, utilisez les. Sinon, utilisez une boucle foreach() ou l’appel
system() à la place.
– Pour conserver la portabilité, quand vous utilisez des fonctionnalités qui ne seront peut-être pas implémentées sur toutes les
machines, testez les instructions dans un eval pour voir si elles échouent. Si vous savez à partir de quelle version et quel niveau
de patch la fonctionnalité a été implémentée, vous pouvez tester $] ($PERL_VERSION en Anglais) pour voir si elle est présente.
Le module Config vous permettra aussi de savoir quelles options ont été retenues par le programme Con?gure quand Perl a été
installé.
– Choisissez des identi?cateurs ayant un sens mnémonique. Si vous n’arrivez pas à vous rappeler à quoi ils correspondent, vous
avez un problème.
– Bien que les petits identi?cateurs comme $gotit soient compréhensibles, les longs sont plus lisibles si les mots sont séparés par des
underscores. Il est plus facile de lire $un_nom_de_variable que $UnNomDeVariable, surtout pour ceux qui ne parlent pas très bien
la langue dans laquelle le programme a été écrit. C’est aussi une règle simple qui marche aussi avec UN_NOM_DE_VARIABLE.
Les noms de paquetages font parfois exception à la règle. Perl réserve de façon informelle des noms de modules en minuscules
pour des modules "pragma" tels integer ou strict. Les autres modules devraient commencer avec une majuscule et utiliser une
casse variée, mais ne mettez pas d’underscores à cause des limitations dans les noms des modules sur certains systèmes de ?chiers
primitifs qui ne permettent que quelques caractères.
– Vous pouvez trouver utile de laisser la casse indiquer la visibilité ou la nature d’une variable. Par exemple :
$TOUT_EN_MAJUSCULES
les constantes uniquement (attention
aux collisions avec les variables internes
de Perl !)
$Quelques_majuscules
variables globales/statiques
$pas_de_majuscule
internes à une fonction (my () ou local())
Les noms de fonctions et de méthodes semblent mieux marcher quand elles sont en minuscule. Ex : $obj->as_string().
Vous pouvez utiliser un underscore au début de la variable pour indiquer qu’elle ne doit pas être utilisée hors du paquetage qui la
dé?nit.
– Si vous avez une expression régulière de la mort, utilisez le modi?cateur /x et ajoutez un peu d’espaces pour que cela ressemble
un peu plus à quelque chose. N’utilisez pas de slash comme délimiteurs quand votre regexp contient des slash ou des antislash.
– Utilisez les nouveaux opérateurs "and" et "or" pour éviter d’avoir à mettre trop de parenthèses dans les listes d’opérations et pour
réduire l’utilisation des opérateurs tels && et ||. Appelez vos routines comme s’il s’agissait de fonctions ou d’opérateurs de listes
pour éviter le surplus de parenthèses et de "&".
– Utilisez des here (opérateur <<) plutôt que des instructions print() répétés.
– Alignez ce qui correspond verticalement, spécialement si c’est trop long pour tenir sur une seule ligne.
$IDX = $ST_MTIME;
$IDX = $ST_ATIME
if $opt_u;
$IDX = $ST_CTIME
if $opt_c;
$IDX = $ST_SIZE
if $opt_s;
155

10.2. VERSION FRANÇAISE
perlstyle
mkdir $tmpdir, 0700 or die "je peux pas faire mkdir $tmpdir: $!";
chdir($tmpdir)
or die "je peux pas faire chdir $tmpdir: $!";
mkdir ’tmp’,
0777 or die "je peux pas faire mkdir $tmpdir/tmp: $!";
Véri?ez toujours la valeur retournée par un appel système. Les meilleurs messages d’erreur sont ceux qui sont dirigés sur STDERR
et qui fournissent : le programme en cause, l’appel système qui a échoué avec ses arguments et (TRÈS IMPORTANT) le message
d’erreur système indiquant la cause de l’échec. Voici un exemple simple, mais suf?sant :

opendir(D, $dir)
or die "je peux pas faire opendir $dir: $!";
– Alignez vos translitérations quand cela a un sens :
tr [abc]
[xyz];
Pensez à la réutilisation du code. Pourquoi faire un code jetable alors que vous aurez certainement à refaire quelque chose de
similaire dans quelque temps. Pensez à généraliser votre code. Pensez à écrire un module ou une classe. Pensez à faire tourner
votre code proprement avec use strict et use warnings (ou -w) activés. Pensez à distribuer votre code. Pensez à changer votre
regard sur le monde. Pensez à  oh, non, oubliez.
– Soyez cohérents.
– Soyez gentils.
10.2
VERSION FRANÇAISE
Cette traduction française correspond à la version anglaise distribuée avec perl 5.6.1. Pour en savoir plus concernant ces traductions,
consultez ;.
10.3
TRADUCTION
Traduction initiale : Matthieu Arnold <>
Mise à jour v5.6.0 : Paul Gaborit <>
10.4
RELECTURE
Personne pour l’instant.
156

Chapitre 11
perltrap – Les pièges de Perl pour l’imprudent
Les pièges de Perl pour l’imprudent
11.1
DESCRIPTION
Le plus grand des pièges est d’oublier d’utiliser l’option -w ; voir le manuel perlrun. Le deuxième plus grand piège est de ne pas
rendre la totalité de votre programme exécutable sous use strict. Le troisième plus grand piège est de ne pas lire la liste des
changements effectués dans cette version de Perl ; voir le manuel perldelta.
11.1.1
Les Pièges de Awk
Les utilisateurs avertis de awk devraient se soucier particulièrement de ce qui suit :
– Le module English, chargé par
use English;
vous permet de vous référer aux variables spéciales (comme $/) par des noms (comme $RS), comme si elles étaient en awk ; voir
le manuel perlvar pour plus de détails.
– Le point-virgule est requis après toute instruction simple en Perl (sauf à la ?n d’un bloc). La ?n de ligne n’est pas un délimiteur
d’instruction.
– Les accolades sont requises pour les ifs et les whiles.
– Les variables commencent par "$", "@" ou "%" en Perl.
– Les tableaux sont indexés à partir de 0. De la même manière, les positions renvoyées par substr() et index() dans les chaînes sont
comptées à partir de 0.
– Vous devez décider si votre tableau a pour indices des nombres ou des chaînes.
– Les hachages ne sont pas créés par une simple référence.
– Vous devez décider si une comparaison porte sur des chaînes ou des nombres.
– La lecture d’une entrée ne la découpe pas pour vous. Vous devez la transformer en un tableau vous-même. Et l’opérateur split() a
des arguments différents qu’en awk.
– La ligne courante en entrée est normalement dans $_, pas dans $0. Elle n’a en général pas encore perdu sa ?n de ligne ($0 est le
nom du programme exécuté). Voir le manuel perlvar.
– $digit ne se réfère pas à des champs – il se réfère aux sous-chaînes détectées par le dernier motif de correspondance.
– L’instruction print() n’ajoute pas de séparateurs de champs et d’enregistrements à moins que vous ne ?xiez $, et $\. Vous pouvez
?xer $OFS et $ORS si vous utilisez le module English.
– Vous devez ouvrir vos ?chiers avant d’y écrire.
– L’opérateur d’intervalle est "..", et pas la virgule. L’opérateur virgule fonctionne comme en C.
– L’opérateur de correspondance est "=˜", pas "˜" ("˜" est l’opérateur de complément à 1, comme en C).
– L’opérateur d’exponentiation est "**", pas "ˆ". "ˆ" est l’opérateur XOR, comme en C (vous savez, on pourrait ?nir par avoir la
sensation que awk est intrinsèquement incompatible avec C).
– L’opérateur de concaténation est ".", pas la chaîne vide (utiliser la chaîne vide rendrait /pat/ /pat/ impossible à analyser
lexicalement, car le troisième signe de division serait interprété comme un opérateur de division – le détecteur de mots-clés est en
fait légèrement sensible au contexte pour les opérateurs tels que "/", "?", et ">". Et en fait, "." lui-même peut être le début d’un
nombre).
– Les mots-clés next, exit, et continue fonctionnement différemment.
– Les variables suivantes fonctionnent différemment :
157

11.1. DESCRIPTION
perltrap
Awk
Perl
ARGC
$#ARGV ou @ARGV scalaire
ARGV[0]
$0
FILENAME
$ARGV
FNR
$. - quelque chose
FS
(ce que vous voulez)
NF
$#Fld, ou quelque chose comme ça
NR
$.
OFMT
$#
OFS
$,
ORS
$\
RLENGTH
length($&)
RS
$/
RSTART
length($‘)
SUBSEP
$;
Vous ne pouvez pas mettre un motif dans $RS, seulement une chaîne.
– En cas de doute, faites passer la construction awk dans a2p et voyez ce que cela donne.
11.1.2
Les Pièges de C
Les programmes C cérébraux devraient prendre note de ce qui suit :
– Les accolades sont requises pour les ifs et les whiles.
– Vous devez utiliser elsif à la place de else if.
– Les mots-clés break et continue de C deviennent respectivement last et next en Perl. Contrairement au C, ceux-ci ne fonc-
tionnent pas à l’intérieur d’une structure do { } while.
– Il n’y a pas d’instruction switch (mais il est aisé d’en construire une à la volée).
– Les variables commencent par "$", "@" ou "%" en Perl.
– printf() n’implémente pas le format "*" interpolant les largeurs de champs, mais il est trivial d’utiliser l’interpolation de chaînes
entre guillemets pour obtenir le même résultat.
– Les commentaires commencent par "#", pas par "/*".
– Vous ne pouvez pas prendre l’adresse de quelque chose, bien qu’un opérateur analogue en Perl est la barre oblique inverse, qui
crée une double référence (hein ? NDT).
– ARGV doit être en majuscules. $ARGV[0] est l’argv[1] du C, et argv[0] atterrit dans $0.
– Les appels systèmes tels que link(), unlink(), rename(), etc. renvoient autre chose que zéro en cas de succès.
– Les handlers de signaux manipulent des noms de signaux, pas des nombres. Utilisez kill -l pour déterminer leurs noms sur
votre système.
11.1.3
Les Pièges de Sed
Les programmeurs sed expérimentés devraient prendre note de ce qui suit :
– Les références arrières dans les substitutions utilisent "$" à la place de "\".
– Les métacaractères d’expressions rationnelles "(", ")", et "|" ne sont pas précédés de barres obliques inverses.
– L’opérateur d’intervalle est  , à la place de la virgule.
11.1.4
Les Pièges du Shell
les programmeurs shell dégourdis devraient prendre note de ce qui suit :
– L’opérateur accent grave effectue une interpolation de variable sans se soucier de la présence ou non d’apostrophes dans la
commande.
– L’opérateur accent grave ne fait pas de traduction de la valeur de retour, contrairement au csh.
– Les shells (en particulier csh) effectuent plusieurs niveaux de substitution sur chaque ligne de commande. Perl ne fait de substitu-
tion que dans certaines structures comme les guillemets, les accents graves, les crochets et les motifs de recherche.
– Les shells interprètent les scripts petits bouts par petits bouts. Perl compile tout le programme avant de l’exécuter (sauf les blocs
BEGIN, qu’il exécute lors de la compilation).
– Les arguments sont disponibles via @ARGV, et pas $1, $2, etc.
– L’environnement n’est pas automatiquement mis à disposition sous forme de variables scalaires distinctes.
158

11.1. DESCRIPTION
perltrap
11.1.5
Les Pièges de Perl
Les programmeurs Perl pratiquants devraient prendre note de ce qui suit :
– Souvenez-vous que de nombreuses opérations se comportent différemment selon qu’elles sont appelées dans un contexte de liste
ou dans un contexte scalaire. Voir le manuel perldata pour plus de détails.
– Évitez autant que possible les barewords, en particulier ceux en minuscules. Vous ne pouvez pas dire rien qu’en le regardant si
un bareword est une fonction ou une chaîne. En utilisant les apostrophes pour les chaînes et des parenthèses pour les appels de
fonctions, vous permettrez qu’on ne les confonde jamais.
– Vous ne pouvez pas distinguer, par une simple inspection, les fonctions intégrées qui sont des opérateurs unaires (comme chop()
et chdir()) de celles qui sont des opérateurs de liste (comme print() et unlink()). (Les sous-programmes dé?nis par l’utilisateur ne
peuvent être que des opérateurs de liste, jamais des opérateurs unaires). Voir le manuel perlop.
– Les gens ont du mal à se souvenir que certaines fonctions utilisent par défaut $_, ou @ARGV, ou autre chose, tandis que d’autres
ne le font pas alors qu’on pourrait s’y attendre.
– La structure <FH> n’est pas le nom du handle de ?chier, c’est un opérateur lisant une ligne sur ce handle. Les données lues sont
affectées à $_ seulement si la lecture du ?chier est la seule condition d’une boucle while :
while (<FH>)
{ }
while (defined($_ = <FH>)) { }..
<FH>;
# données rejetées !
Souvenez-vous de ne pas utiliser = lorsque vous avez besoin de =˜ ; ces deux structures sont très différentes :

$x =
/foo/;
$x =~ /foo/;
– La structure do {} n’est pas une vraie boucle sur laquelle vous pouvez utiliser un contrôle de boucle (? NDT).
– Utilisez my() pour les variables locales chaque fois que vous pouvez vous en satisfaire (mais voyez le manuel perlform pour les
cas où vous ne le pouvez pas). L’utilisation de local() donne vraiment une valeur locale à une variable globale, ce qui vous met
à la merci d’effets secondaires de portée dynamique imprévus.
– Si vous localisez une variable exportée dans un module, sa valeur exportée value ne changera pas. Le nom local devient un alias
pour une nouvelle valeur, mais le nom externe est toujours un alias de l’original.
11.1.6
Les Pièges entre Perl4 et Perl5
Les programmeurs Perl4 pratiquants devraient prendre note des pièges suivants, spéci?ques au passage entre Perl4 et Perl5.
Ils sont crûment commandés par la liste suivante :
Pièges liés aux Corrections de Bugs, aux Désapprobations et aux Abandons
Tout ce qui a été corrigé en tant que bug de perl4, supprimé ou désapprouvé en tant que caractéristique de perl4, avec l’intention
d’encourager l’usage d’une autre caractéristique de perl5.
Pièges de l’Analyse Syntaxique
Pièges qui semblent provenir du nouvel analyseur.
Pièges numériques
Pièges liés aux opérateurs numériques ou mathématiques.
Pièges des Types Généraux de données
Pièges impliquant les types de données standards de perl.
Pièges du Contexte - contexte scalaire et de liste
Pièges liés au contexte dans les instructions et déclarations scalaires ou de liste.
Pièges de la Précédence
Pièges liés à la précédence lors de l’analyse, de l’évaluation et de l’exécution du code.
Pièges des Expressions Rationnelles Générales lors de l’utilisation de s///, etc.
Pièges liés à l’utilisation de la reconnaissance de motifs.
Pièges des Sous-Programmes, des Signaux, des Tris
Pièges liés à l’utilisation des signaux et des handlers de signaux, aux sous-programmes généraux, et aux tris, ainsi qu’aux
sous-progammes de tri.
Pièges de l’OS
Pièges spéci?ques au système d’exploitation.
Pièges du DBM
Pièges spéci?ques à l’utilisation de dbmopen(), et aux implémentations particulières de dbm.
159

11.1. DESCRIPTION
perltrap
Pièges non Classés
Tout le reste.
Si vous trouvez un exemple de piège de conversion qui ne soit pas listé ici, soumettez-le à Bill Middleton <> en vue
de son inclusion. Notez aussi qu’au moins certains de ceux qui suivent peuvent être capturés par le pragma use warnings ou par
l’option -w.
11.1.7
Pièges liés aux Corrections de Bugs, aux Désapprobations et aux Abandons
Tout ce qui a été abandonné, désapprouvé ou corrigé comme étant un bug depuis perl4.
– Abandon
Les symboles commençant par "_" ne sont plus forcément dans le paquetage main, sauf pour $_ lui-même (ainsi que @_, etc.).
package test;
$_legacy = 1;
package main;
print "\$_legacy is ",$_legacy,"\n";
# perl4 affiche : $_legacy is 1
# perl5 affiche : $_legacy is
– Désapprobation
Le double deux-points est désormais un séparateur de paquetage valide dans un nom de variable. Ainsi ceux-ci se comportent
différemment en perl4 et en perl5, car le paquetage n’existe pas.
$a=1;$b=2;$c=3;$var=4;
print "$a::$b::$c ";
print "$var::abc::xyz\n";
# perl4 affiche : 1::2::3 4::abc::xyz
# perl5 affiche : 3
Étant donné que :: est maintenant le délimiteur de paquetage préféré, on peut se demander si ceci doit être considéré comme un
bug ou non (l’ancien délimiteur de paquetage, ’ , est utilisé ici).
$x = 10 ;
print "x=${’x}\n" ;
# perl4 affiche : x=10
# perl5 affiche : Can’t find string terminator "’" anywhere before EOF
Vous pouvez éviter ce problème, en restant compatible avec perl4, si vous incluez toujours explicitement le nom du paquetage :
$x = 10 ;
print "x=${main’x}\n" ;
Voyez aussi les pièges de précédence, pour l’analyse de $:.
– Correction de Bug
Les deuxièmes et troisièmes arguments de splice() sont désormais évalués dans un contexte scalaire (comme l’indique le Camel)
plutôt que dans un contexte de liste.
sub sub1{return(0,2) }
# retourne une liste de 2 éléments
sub sub2{ return(1,2,3)}
# retourne une liste de 3 éléments
@a1 = ("a","b","c","d","e");
@a2 = splice(@a1,&sub1,&sub2);
print join(’ ’,@a2),"\n";
# perl4 affiche : a b
# perl5 affiche : c d e
– Abandon
Vous ne pouvez pas faire un goto dans un bloc optimisé. Mince.
goto marker1;
for(1){
marker1:
print "Here I is!\n";
}
# perl4 affiche : Here I is!
# perl5 effectue un vidage mémoire (SEGV)
– Abandon
Il n’est plus légal syntaxiquement d’utiliser l’espace comme nom de variable, ou comme délimiteur pour tout type de structure
entre apostrophes. Mince et remince.
160

11.1. DESCRIPTION
perltrap
$a = ("foo bar");
$b = q baz ;
print "a is $a, b is $b\n";
# perl4 affiche : a is foo bar, b is baz
# erreur de perl5 : Bareword found where operator expected
– Abandon
La syntaxe archaïque while/if BLOC BLOC n’est plus supportée.
if { 1 } {
print "True!";
}
else {
print "False!";
}
# perl4 affiche : True!
# erreur de perl5 : syntax error at  line 1, near "if {"
– Correction de Bug
L’opérateur ** se lie désormais plus étroitement que le moins unaire. Cela devait fonctionner ainsi selon la documentation, mais
ce n’était pas le cas.
print -4**2,"\n";
# perl4 affiche : 16
# perl5 affiche : -16
– Abandon
La signi?cation de foreach{} a légèrement changé lorsqu’il traverse une liste qui n’est pas un tableau. C’était utilisé pour affecter
la liste à un tableau temporaire, mais ce n’est plus le cas (pour des raisons d’ef?cacité). Cela veut dire que vous devrez désormais
itérer sur les vraies valeurs, pas sur des copies de ces valeurs. Les modi?cations de la variable de boucle peuvent changer les
valeurs originelles.
@list = (’ab’,’abc’,’bcd’,’def’);
foreach $var (grep(/ab/,@list)){
$var = 1;
}
print (join(’:’,@list));
# perl4 affiche : ab:abc:bcd:def
# perl5 affiche : 1:1:bcd:def
Pour garder la sémantique de Perl4, vous devrez affecter explicitement votre liste à un tableau temporaire puis itérer dessus. Vous
pourriez par exemple devoir changer
foreach $var (grep(/ab/,@list)){
en
foreach $var (@tmp = grep(/ab/,@list)){
Sinon changer $var modi?era les valeurs de @list (Cela arrive le plus souvent lorsque vous utilisez $_ comme variable de boucle,
et appelez dans celle-ci des sous-programmes qui ne localisent pas correctement $_).
– Abandon
split sans argument se comporte désormais comme split ’ ’ (qui ne retourne pas de champ nul initial si $_ commence par
une espace), il se comportait habituellement comme split /\s+/ (qui le fait).
$_ = ’ hi mom’;
print join(’:’, split);
# perl4 affiche : :hi:mom
# perl5 affiche : hi:mom
– Correction de Bug
Perl 4 ignorait tout texte attaché à une option -e, et prenait toujours le petit bout de code dans l’argument suivant. Qui plus est, il
acceptait silencieusement une option -e non suivie d’un argument. Ces deux comportements ont été supprimés.
perl -e’print "attached to -e"’ ’print "separate arg"’
# perl4 affiche : separate arg
# perl5 affiche : attached to -e
perl -e
# perl4 affiche :
# perl5 meurt : No code specified for -e.
– Abandon
En Perl 4, la valeur de retour de push n’était pas documentée, mais c’était en fait la dernière valeur poussée sur la liste cible. En
Perl 5, la valeur de retour de push est documentée, mais elle a changé, c’est désormais le nombre d’éléments de la liste résultante.
@x = (’existing’);
161

11.1. DESCRIPTION
perltrap
print push(@x, ’first new’, ’second new’);
# perl4 affiche : second new
# perl5 affiche : 3
– Désapprobation
Certains messages d’erreur sont différents.
– Abandon
Certains bugs peuvent avoir été retirés par inadvertence. :-)
11.1.8
Piège de l’Analyse Syntaxique
Pièges entre Perl4 et Perl5 ayant un rapport avec l’analyse syntaxique.
– Analyse Syntaxique
Notez l’espace entre . et =
$string . = "more string";
print $string;
# perl4 affiche: more string
# perl5 affiche : syntax error at - line 1, near ". ="
– Analyse Syntaxique
L’analyse est meilleure en perl 5
sub foo {}
&foo
print("hello, world\n");
# perl4 affiche : hello, world
# perl5 affiche : syntax error
– Analyse Syntaxique
Règle "si ça a l’air d’une fonction, c’est une fonction".
print
($foo == 1) ? "is one\n" : "is zero\n";
# perl4 affiche : is zero
# perl5 avertit : "Useless use of a constant in void context" if using -w
– Analyse Syntaxique
L’interpolation de chaîne de la structure $#array diffère lorsque des accolades sont utilisées autour du nom.
@ = (1..3);
print "${#a}";
# perl4 affiche : 2
# perl5 échoue sur une erreur de syntaxe
@ = (1..3);
print "$#{a}";
# perl4 affiche : {a}
# perl5 affiche : 2
11.1.9
Pièges Numériques
Pièges entre Perl4 et Perl5 ayant un rapport avec les opérateurs numériques, les opérandes, ou leurs sorties.
– Numérique
Sortie formattée et chiffres signi?catifs
print 7.373504 - 0, "\n";
printf "%20.18f\n", 7.373504 - 0;
# Perl4 affiche :
7.375039999999996141
7.37503999999999614
# Perl5 affiche :
7.373504
7.37503999999999614
– Numérique
Cet élément spéci?que a été supprimé. Il démontrait comment l’opérateur d’auto-incrémentation ne voyait pas qu’un nombre avait
dépassé la limite supérieure des entiers signés. Cela a été réglé dans la version 5.003_04. Mais soyez toujours prudent lorsque
vous utilisez de grands entiers. En cas de doute :
162

11.1. DESCRIPTION
perltrap
use Math::BigInt;
– Numérique
L’affectation de valeurs de retour de tests d’égalité numérique ne fonctionne pas en perl5 lorsque le test échoue (et renvoit 0). Les
tests logique retourne maintenant un null, au lieu de 0
$p = ($test == 1);
print $p,"\n";
# perl4 affiche : 0
# perl5 affiche :
Voir aussi §11.1.13 pour un autre exemple de cette nouvelle caractéristique
– Opérateurs de chaîne bit par bit
Lorsque des opérateurs bit par bit qui peuvent travailler sur des nombres ou sur des chaînes (& | ˆ ˜) n’ont que des chaînes pour
arguments, perl4 traite les opérandes comme des chaînes de bits dans la mesure où le programme contenait un appel à la fonction
vec(). perl5 traite les opérandes chaînes comme des chaînes de bits (Voir le titre Opérateurs bit à bit sur les chaînes dans le
manuel perlop pour plus de détails).
$fred = "10";
$barney = "12";
$betty = $fred & $barney;
print "$betty\n";
# Décommentez la ligne suivante pour changer le comportement de perl4
# ($dummy) = vec("dummy", 0, 0);
# Perl4 affiche :
8
# Perl5 affiche :
10
# Si vec() est utilisé quelque part dans le programme, les deux
# affichent :
10
11.1.10
Pièges des Types de Données Généraux
Pièges entre Perl4 et Perl5 impliquant la plupart des types de données, et leur usage dans certaines expressions et/ou contextes.
– (Tableaux)
Les indices de tableau négatifs sont maintenant comptés depuis la ?n du tableau.
@a = (1, 2, 3, 4, 5);
print "The third element of the array is $a[3] also expressed as $a[-2] \n";
# perl4 affiche : The third element of the array is 4 also expressed as
# perl5 affiche : The third element of the array is 4 also expressed as 4
– (Tableaux)
Abaisser la valeur de $#array supprime désormais des éléments du tableau, et rend impossible leur récupération.
@a = (a,b,c,d,e);
print "Before: ",join(’’,@a);
$#a =1;
print ", After: ",join(’’,@a);
$#a =3;
print ", Recovered: ",join(’’,@a),"\n";
# perl4 affiche : Before: abcde, After: ab, Recovered: abcd
# perl5 affiche : Before: abcde, After: ab, Recovered: ab
– (Hachages)
Les hachages sont dé?nis avant leur utilisation
local($s,@a,%h);
die "scalar \$s defined" if defined($s);
die "array \@a defined" if defined(@a);
die "hash \%h defined" if defined(%h);
# perl4 affiche :
# perl5 meurt : hash %h defined
Perl génère désormais un avertissement lorsqu’il voit de?ned(@a) et de?ned(%h).
– (Globs)
L’affectation globale de variable à variable échouera si la variable affectée est localisée après l’affectation
@a = ("This is Perl 4");
163

11.1. DESCRIPTION
perltrap
*b = *a;
local(@a);
print @b,"\n";
# perl4 affiche : This is Perl 4
# perl5 affiche :
– (Globs)
L’affectation de undef à un glob n’a pas d’effet en Perl 5. En Perl 4, elle indé?nit le scalaire associé (mais peut avoir d’autres
effets de bord, y compris des SEGVs).
– (Chaîne Scalaire)
Changements dans la négation unaire (de chaînes) Ce changement affecte à la fois la valeur de retour et ce qu’elle fait à l’incrément
automagique.
$x = "aaa";
print ++$x," : ";
print -$x," : ";
print ++$x,"\n";
# perl4 affiche : aab : -0 : 1
# perl5 affiche : aab : -aab : aac
– (Constantes)
perl 4 vous laisse modi?er les constantes :
$foo = "x";
&mod($foo);
for ($x = 0; $x < 3; $x++) {
&mod("a");
}
sub mod {
print "before: $_[0]";
$_[0] = "m";
print "
after: $_[0]\n";
}
# perl4:
# before: x
after: m
# before: a
after: m
# before: m
after: m
# before: m
after: m
# Perl5:
# before: x
after: m
# Modification of a read-only value attempted at  line 12.
# before: a
– (Scalaires)
Le comportement est légèrement différent pour :
print "$x", defined $x
# perl 4: 1
# perl 5: <no output, $x is not called into existence>
– (Suicide de Variable)
Le suicide de variable est plus cohérent sous Perl 5. Perl5 montre le même comportement pour les hachages et les scalaires, que
perl4 montre uniquement pour les scalaires.
$aGlobal{ "aKey" } = "global value";
print "MAIN:", $aGlobal{"aKey"}, "\n";
$GlobalLevel = 0;
&test( *aGlobal );
sub test {
local( *theArgument ) = @_;
local( %aNewLocal ); # perl 4 != 5.001l,m
$aNewLocal{"aKey"} = "this should never appear";
print "SUB: ", $theArgument{"aKey"}, "\n";
$aNewLocal{"aKey"} = "level $GlobalLevel";
# what should print
$GlobalLevel++;
if( $GlobalLevel<4 ) {
&test( *aNewLocal );
}
164

11.1. DESCRIPTION
perltrap
}
# Perl4:
# MAIN:global value
# SUB: global value
# SUB: level 0
# SUB: level 1
# SUB: level 2
# Perl5:
# MAIN:global value
# SUB: global value
# SUB: this should never appear
# SUB: this should never appear
# SUB: this should never appear
11.1.11
Pièges du Contexte - contextes scalaires et de liste
– (contexte de liste)
Les éléments des listes d’arguments pour les formats sont désormais évalués dans un contexte de liste. Cela signi?e que vous
pouvez maintenant interpoler les valeurs de liste.
@fmt = ("foo","bar","baz");
format STDOUT=
@<<<<< @||||| @>>>>>
@fmt;
.
write;
# erreur de perl4 :
Please use commas to separate fields in file
# perl5 affiche : foo
bar
baz
– (contexte scalaire)
La fonction caller() retourne maintenant la valeur faux dans un contexte scalaire s’il n’y a pas d’appelant. Cela laisse les ?chiers
de bibliothèque déterminer s’ils sont en train d’être demandés.
caller() ? (print "You rang?\n") : (print "Got a 0\n");
# erreur de perl4 : There is no caller
# perl5 affiche : Got a 0
– (contexte scalaire)
L’opérateur virgule dans un contexte scalaire est désormais garanti comme donnant un contexte scalaire à ses arguments.
@y= (’a’,’b’,’c’);
$x = (1, 2, @y);
print "x = $x\n";
# Perl4 affiche :
x = c
# pense contexte de liste,
# interpole la liste
# Perl5 affiche :
x = 3
# sait que le scalaire utilise la
# longueur de la liste
– (liste, fonction intégrée)
Couardise de sprintf() (argument tableau converti en nombre scalaire d’éléments du tableau) Ce test pourrait être ajouté à
t/op/sprintf.t
@z = (’%s%s’, ’foo’, ’bar’);
$x = sprintf(@z);
if ($x eq ’foobar’) {print "ok 2\n";} else {print "not ok 2 ’$x’\n";}
# perl4 affiche : ok 2
# perl5 affiche : not ok 2
printf() fonctionne toutefois bien :
printf STDOUT (@z);
print "\n";
# perl4 affiche : foobar
# perl5 affiche : foobar
Probablement un bug.
11.1.12
Pièges de la Précédence
Pièges entre Perl4 et Perl5 impliquant l’ordre de précédence.
165

11.1. DESCRIPTION
perltrap
Perl 4 a presque les mêmes règles de précédence que Perl 5 pour les opérateurs qu’ils ont en commun. Toutefois, Perl 4 semble avoir
contenu des incohérences ayant rendu son comportement différent de celui qui était documenté.
– Précédence
LHS vs. RHS pour tout opérateur d’affectation. LHS est d’abord évalué en perl4, mais en second en perl5 ; ceci peut modi?er les
relations entre les effets de bord dans les sous-expressions.
@arr = ( ’left’, ’right’ );
$a{shift @arr} = shift @arr;
print join( ’ ’, keys %a );
# perl4 affiche : left
# perl5 affiche : right
– Précédence
Voici des expressions devenues des erreurs sémantiques à cause de la précédence :
@list = (1,2,3,4,5);
%map = ("a",1,"b",2,"c",3,"d",4);
$n = shift @list + 2;
# premier élément de la liste plus 2
print "n is $n, ";
$m = keys %map + 2;
# nombre d’éléments du hachage plus 2
print "m is $m\n";
# perl4 affiche : n is 3, m is 6
# erreur de perl5 et échec de la compilation
– Précédence
La précédence des opérateurs d’affectation est désormais la même que celle de l’affectation. Perl 4 leur donnait par erreur la
précédence de l’opérateur associé. Vous devez donc maintenant les mettre entre parenthèses dans les expressions telles que
/foo/ ? ($a += 2) : ($a -= 2);
Autrement
/foo/ ? $a += 2 : $a -= 2
serait analysé de façon erronée sous la forme
(/foo/ ? $a += 2 : $a) -= 2;
D’autre part,
$a += /foo/ ? 1 : 2;
fonctionne désormais comme un programmeur C pourrait s’y attendre.
– Précédence
open FOO || die;
est désormais incorrect. Vous devez mettre le handle de ?chier entre parenthèses. Sinon, perl5 laisse sa précédence par défaut à
l’instruction :
open(FOO || die);
# perl4 ouvre ou meurt
# erreur de perl5 : Precedence problem: open FOO should be open(FOO)
– Précédence
perl4 donne la précédence à la variable spéciale $:, tandis que perl5 traite $:: comme étant le paquetage principale
$a = "x"; print "$::a";
# perl 4 affiche : -:a
# perl 5 affiche : x
– Précédence
perl4 a une précédence bugguée pour les opérateurs de test de ?chiers vis-à-vis des opérateurs d’affectation. Ainsi, bien que la
table de précédence de perl4 laisse à penser que -e $foo .= "q" devrait être analysé comme ((-e $foo) .= "q"), il l’analyse
en fait comme (-e ($foo .= "q")). En perl5, la précédence est telle que documentée.
-e $foo .= "q"
# perl4 affiche : no output
# perl5 affiche : Can’t modify -e in concatenation
– Précédence
En perl4, keys(), each() et values() étaient des opérateurs spéciaux de haute précédence qui agissaient sur un simple hachage, mais
en perl5, ce sont des opérateurs unaires nommés normaux. Tels que documentés, ces opérateurs ont une précédence plus basse
que les opérateurs arithmétiques et de concaténation + - ., mais les variantes de perl4 de ces opérateurs se lient en fait plus
étroitement que + - .. Ainsi, pour :
%foo = 1..10;
print keys %foo - 1
# perl4 affiche : 4
# perl5 affiche : Type of arg 1 to keys must be hash (not subtraction)
Le comportement de perl4 était probablement plus utile, mais moins cohérent.
166

11.1. DESCRIPTION
perltrap
11.1.13
Pièges des Expressions Rationnelles Générales lors de l’utilisation de s///, etc.
Tous types de pièges concernant les expressions rationnelles.
– Expression Rationnelle
s’$lhs’$rhs’ n’effectue désormais d’interpolation ni d’un côté ni de l’autre. $lhs était habituellement interpolé, mais pas $rhs
(et ne détecte toujours pas un ’$’ littéral dans la chaîne)
$a=1;$b=2;
$string = ’1 2 $a $b’;
$string =~ s’$a’$b’;
print $string,"\n";
# perl4 affiche : $b 2 $a $b
# perl5 affiche : 1 2 $a $b
– Expression Rationnelle
m//g attache maintenant son état à la chaîne fouillée plutôt que l’expression rationnelle (une fois que la portée d’un bloc est quittée
pour le sous-programme, l’état de la chaîne fouillée est perdu)
$_ = "ababab";
while(m/ab/g){
&doit("blah");
}
sub doit{local($_) = shift; print "Got $_ "}
# perl4 affiche : blah blah blah
# perl5 affiche : boucle infinie de blah
– Expression Rationnelle
Couramment, si vous utilisez le quali?cateur m//o sur une expression rationnelle dans un sous-programme anonyme, toutes les
fermetures générées dans ce sous-programme anonyme utiliseront l’expression rationnelle telle qu’elle a été compilée lors de sa
toute première utilisation dans une telle fermeture. Par exemple, si vous dites
sub build_match {
my($left,$right) = @_;
return sub { $_[0] =~ /$left stuff $right/o; };
}
build_match() retournera toujours un sous-programme qui correspondra au contenu de $left et de $right tels qu’ils étaient la
première fois que build_match() a été appelé, et pas tels qu’ils sont dans l’appel en cours.
C’est probablement un bug, et cela pourrait changer dans les futures versions de Perl.
– Expression Rationnelle
Si aucune parenthèse n’est utilisée dans une correspondance, Perl4 ?xe $+ à toute la corerspondance, tout comme $&. Perl5 ne le
fait pas.
"abcdef" =~ /b.*e/;
print "\$+ = $+\n";
# perl4 affiche : bcde
# perl5 affiche :
– Expression Rationnelle
La substitution retourne désormais la chaîne vide si elle échoue
$string = "test";
$value = ($string =~ s/foo//);
print $value, "\n";
# perl4 affiche : 0
# perl5 affiche :
Voir aussi le titre Pièges Numériques dans ce document pour un autre exemple de cette nouvelle caractéristique.
– Expression Rationnelle
s‘lhs‘rhs‘ (en utilisant des accents