IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Programmation en PERL

de Larry Wall, Tom Christiansen et Jon Orwant


précédentsommairesuivant

V. Références

28. Noms spéciaux

Ce chapitre traite des variables qui ont une signification spéciale pour Perl. La plupart des noms à ponctuation ont des mnémoniques raisonnables ou des homologues dans les shells (ou les deux). Néanmoins, s'il faut utiliser les noms longs de variables, il suffit d'écrire :

 
Sélectionnez
use English;

au début du programme. Ceci crée des alias longs pour les noms courts dans le paquetage courant. Certains d'entre eux ont même des noms moyens, généralement empruntés à awk. La plupart des gens continuent d'utiliser les noms courts, du moins pour les variables les plus courantes. Au long de cet ouvrage, nous employons uniformément les noms courts, mais nous mentionnerons aussi les noms longs (entre parenthèses) pour que vous puissiez facilement les retrouver dans ce chapitre.

La sémantique de ces variables est quelque peu magique (pour créer vos propres sorts, voir le chapitre 24, Variables liées). Certaines de ces variables sont en lecture seule. Si l'on essaie d'y assigner une valeur, une exception sera lancée.

Dans ce qui suit, nous donnerons tout d'abord une liste des variables et fonctions auxquelles Perl attribue une signification spéciale, classées par type ; ainsi vous pourrez retrouver les variables dont vous n'êtes plus tout à fait sûrs du nom exact. Ensuite nous détaillerons toutes les variables par ordre alphabétique, avec leur nom approprié (ou leur nom le moins inapproprié).

28-1. Noms spéciaux classés par type

Nous utilisons improprement le mot « type », les sections suivantes regroupent davantage les variables selon leur contexte, c'est-à-dire depuis l'endroit où elles sont visibles.

28-1-a. Variables spéciales des expressions régulières

Les variables spéciales suivantes sont associées à la recherche de motifs. Elles sont visibles tout au long du contexte dans lequel la recherche a lieu (hormis $*, qui est dépréciée). Autrement dit, elles se comportent comme si elles étaient déclarées avec local, vous n'avez donc pas besoin de les déclarer ainsi vous-même. Voir le chapitre 5, Reconnaissance de motifs.

 
Sélectionnez
$*
$chiffres
@+ (@LAST_MATCH_END)
@-(@LAST_MATCH_START)
$+ ($LAST_PAREN_MATCH)
$^R ($LAST_REGEXP_CODE_RESULT)
$& ($MATCH)
$' ($POSTMATCH)
$' ($PREMATCH)
28-1-b. Variables spéciales des handles de fichiers

Ces variables spéciales n'ont jamais besoin d'être mentionnées dans un local car elles se réfèrent toujours à des valeurs appartenant au handle de sortie actuellement sélectionné — chaque handle de fichier garde son propre jeu de valeurs. Quand on sélectionne un autre handle de fichier, l'ancien garde ses valeurs et les variables reflètent alors les valeurs du nouveau handle de fichier. Voir aussi le module FileHandle dans le chapitre 32, Modules standards.

 
Sélectionnez
$| ($AUTOFLUSH, $OUTPUT_AUTOFLUSH)
$-($FORMAT_LINES_LEFT)
$= ($FORMAT_LINES_PER_PAGE)
$~ ($FORMAT_NAME)
$% ($FORMAT_PAGE_NUMBER)
$^ ($FORMAT_TO_NAME)
28-1-c. Variables spéciales par paquetage

Ces variables spéciales existent séparément dans chaque paquetage. Il n'est pas besoin de les localiser, puisque sort le fait automatiquement pour $a et $b, et qu'il est probablement préférable de laisser les autres se débrouiller toutes seules (cependant si vous employez use strict, vous devrez les déclarer avec our).

 
Sélectionnez
$a
$b
@EXPORT
@EXPORT_OK
%EXPORT_TAGS
%FIELDS @ISA
%OVERLOAD
$VERSION
28-1-d. Variables spéciales pour le programme entier

Ces variables sont vraiment globales au sens exact du terme — elles signifient la même chose dans chaque paquetage, car elles sont toutes localisées de force dans le paquetage

main lorsqu'elles sont non qualifiées (sauf pour @F, qui est spéciale dans main, mais pas forcée). Si vous voulez une copie temporaire de l'une d'entre elles, vous devez la localiser dans le contexte dynamique courant.

 
Sélectionnez
%ENV                               $< (UID, $REAL_USER_ID)
%INC                               $> (EUID, $EFFECTIVE_USER_ID)
%SIG                               $? ($CHILD_ERROR)
%!                                 $@ ($EVAL_ERROR)
%^H                                $[
                                   $\ ($ORS, $OUTPUT_RECORD_SEPARATOR)
@_                                 $] ($OLD_PERL_VERSION)
@ARGV                              $^A ($ACCUMULATOR)
@F                                 $^C ($COMPILING)
@INC                               $^D ($DEBUGGING)
                                   $^E ($EXTENDED_OS_ERROR)
$_ ($ARG)                          $^F ($SYSTEM_FD_MAX)
$0 ($PROGRAM_NAME)                 $^H
$ARGV                              $^I ($INPLACE_EDIT)
                                   $^L ($FORMA_FORMFEED)
$! ($ERRNO, $OS_ERROR)             $^M
$" ($LIST_SEPARATOR)               $^O ($OSNAME)
$#                                 $^P ($PERLDB)
$$ ($PID, $PROCESS_ID)             $^R ($LAST_REGEXP_DOC_RESULT)
$( ($GID, $REAL_GROUP_ID)          $^S ($EXCEPTION_BEING_CAUGHT)
$) ($EGID, $EFFECTIVE_GROUP_ID)    $^T ($BASETIME)
$, ($OFS, $OUTPUT_FIELD_SEPARATOR) $^V ($PERL_VERSION)
$. ($NR, $INPUT_LINE_NUMBER)       $^W ($WARNING)
$/ ($RS, $INPUT_RECORD_SEPARATOR)  ${^WARNING_BITS}
$: ($FORMAT_LINE_BREAK_CHARACTERS) ${^WIDE_SYSTEM_CALLS}
$; ($SUBSEP, $SUBSCRIPT_SEPARATOR) $^X ($EXECUTABLE_NAME)
28-1-e. Handles de fichiers spéciaux par paquetage

Sauf pour DATA, qui est toujours particulier à un paquetage, les handles de fichiers suivants sont toujours considérés comme étant dans main lorsqu'ils ne sont pas pleinement qualifiés dans un autre paquetage.

 
Sélectionnez
_ (souligné)
ARGV
ARGVOUT
DATA
STDIN
STDOUT
STDERR
28-1-f. Fonctions spéciales par paquetage

Les noms des routines suivantes ont une signification spéciale pour Perl. Elles sont toujours appelées implicitement suite à un événement, comme l'accès à une variable liée ou l'appel d'une fonction indéfinie. Nous ne les décrirons pas dans ce chapitre puisqu'elles sont largement couvertes par ailleurs dans cet ouvrage.

Fonction indéfinie appelant une interception (voir le chapitre 10, Paquetages):

  • AUTOLOAD

Achèvement des objets moribonds (voir le chapitre 12, Objets):

  • DESTROY

Objets d'exception (voir die dans le chapitre suivant) :

  • PROPAGATE

Fonctions d'autoinitialisation et d'autonettoyage (voir le chapitre 18, Compilation):

Méthodes de liaison (voir le chapitre 14) :

  • BINMODE, CLEAR, CLOSE, DELETE, EOF, EXISTS, EXTEND, FETCH, FETCHIZE, FILENO, FIRSTKEY, GETC, NEXTKEY, OPEN, POP, PRINT, PRINTF, PUSH, READ, READLINE, SEEK, SHIFT, SPLICE, STORE, STORESIZE, TELL, TIEARRAY, TIEHANDLE, TIEHASH, TIESCALAR, UNSHIFT, WRITE

28-2. Variables spéciales dans l'ordre alphabétique

Nous avons classé alphabétiquement ces entrées selon le nom long des variables. Si vous ne connaissez pas le nom long d'une variable, vous pouvez le trouver dans la section précédente. (Les variables sans nom alphabétique sont classées au début.)

Pour éviter les répétitions, chaque description de variable débute avec une, ou plusieurs, des annotations suivantes.

Annotation

Signification

XXX

Dépréciée, ne pas utiliser pour quelque chose de nouveau.

NON

Non Officiellement Nommée (pour usage interne seulement).

GLO

Réellement globale, partagée par tous les paquetages.

PKG

Globale au paquetage ; chaque paquetage peut redéfinir sa propre
variable.

AHF

Attribut de handle de fichier ; un attribut par objet d'entrée/sortie.

DYN

Automatiquement dans un contexte dynamique (entraîne GLO).

LEX

Dans un contexte lexicographique à la compilation.

LEC

En lecture seule ; lève une exception si vous tentez de modifier.

Quand plus d'un symbole ou plus d'un nom de variable est mentionné, seul le nom court est disponible par défaut. En utilisant le module English, les synonymes plus longs sont disponibles dans le paquetage courant et uniquement dans le paquetage courant, même si la variable est marquée avec [GLO].

Les entrées de la forme méthode HANDLE EXPR montrent l'interface orientée objet des variables pourvues par FileHandle et les différents modules IO::. (Si vous préférez, vous pouvez aussi utiliser la notation HANDLE->méthode(EXPR)). Ceci vous permet d'éviter d'appeler select pour changer le handle de sortie par défaut avant d'examiner ou de modifier la variable en question. Chacune de ces méthodes renvoie l'ancienne valeur de l'attribut du FileHandle ; l'attribut prend une nouvelle valeur si l'on positionne l'argument EXPR. Si cet argument n'est pas fourni, la plupart des méthodes ne modifient pas la valeur courante, excepté pour autoflush, qui suppose que l'argument vaut 1, uniquement pour se distinguer.

_ (souligné)

  • [GLO] Il s'agit du handle de fichier spécial utilisé pour garder en cache les informations obtenues lors du dernier stat, lstat ou du dernier opérateur de test de fichier (comme -w $file ou -d $file) ayant réussi.

$chiffres

  • [DYN, LEC] Les variables numérotées $1, $2, etc. (aussi élevé que vous le désirez)(197) contiennent le texte trouvé par le jeu de parenthèses correspondant dans la dernière recherche de motifs du contexte dynamique actif à cet instant. (Mnémonique : comme \chiffres).

$[

  • [XXX, LEX] L'index du premier élément d'un tableau et du premier caractère d'une sous-chaîne. 0 par défaut, mais nous utilisons cette variable positionnée à 1 pour que Perl se comporte mieux comme awk (ou FORTRAN) au moment d'indicer et d'évaluer les fonctions index et substr. Parce qu'on a trouvé cette variable dangereuse, l'affectation de $[ est maintenant traitée comme une directive de compilation dans un contexte lexical et ne peut pas influencer le comportement de tout autre fichier. (Mnémonique : [ précède les indices).

$#

  • [XXX, GLO] N'utilisez pas cette variable ; préférez printf. $# contient le format de sortie des nombres imprimés, dans une tentative peu convaincante d'émulation de la variable OFMT de awk. (Mnémonique : # en anglais signifie numéro, mais si vous êtes pointilleux, mieux vaut oublier tout ceci afin de ne pas trop parasiter votre programme et éviter ainsi un sermon).

$*

  • [XXX, GLO] Et bien, trois variables dépréciées à la suite ! Celle-ci peut (mais ne doit pas) être positionnée à vrai pour que Perl assume un /m sur chaque recherche de motif qui n'a pas explicitement de /s. (Mnémonique : * correspond à de multiples quantités).

$a

  • [PKG] Cette variable est utilisée par la fonction sort pour contenir le premier élément de chaque paire de valeurs à comparer ($b est le second élément de chaque paire). Le paquetage pour $a est le même que celui où l'opérateur sort a été compilé, qui n'est pas nécessairement celui dans lequel la fonction de comparaison a été compilée. Cette variable est implicitement localisée dans le bloc de comparaison de sort. Comme elle est globale, elle est exempte des messages de protestation de use strict. Puisque c'est un alias pour la valeur du tableau concerné, on pourrait penser qu'on peut la modifier, n'en faites rien. Voir la fonction sort.

$ACCUMULATOR
$^A

  • [GLO] La valeur courante de l'accumulateur de write pour les lignes de format. Un format contient contient des commandes formline qui émettent leur résultat dans $^A. Après avoir appelé son format, write affiche le contenu de $^A et le vide. On ne voit donc jamais le contenu de $^A à moins d'appeler formline soi-même pour l'examiner. Voir la fonction formline.

$ARG
$_

  • [GLO] L'espace d'entrée et de recherche de motifs par défaut. Ces paires sont équivalentes :

     
    Sélectionnez
    while (<>) {...} # n'est équivalent qu'avec un while sans décorations
    while (defined($_ = <>)) {...}
    chomp
    chomp($_)
    /^Objet:/
    $_ =~ /^Objet:/
    tr/a-z/A-Z/
    $_ = ~ tr/a-z/A-Z/
  • Voici les endroits où Perl prend $_ si l'on ne spécifie pas d'opérande aux fonctions et opérateurs :

    • Des fonctions de listes comme print et unlink et des fonctions unaires comme ord, pos et int, ainsi que tous les tests de fichier (sauf pour -t, qui prend STDIN par défaut). Toutes les fonctions qui prennent par défaut $_ sont repérées en tant que telles dans le chapitre 29, Fonctions.
    • Les opérations de recherche de motifs m// et s/// et les opérations de transformation y/// et tr///, lorsqu'on les utilise sans l'opérateur =~.
    • La variable d'itération dans une boucle foreach (même si on l'épelle for ou lorsqu'on l'utilise avec un modificateur d'instruction) si aucune autre variable n'est fournie.
    • La variable d'itération implicite dans les fonctions grep et map. (Il n'y a aucun moyen de spécifier une variable différente pour ces fonctions.)
    • L'endroit par défaut où est placé un enregistrement en entrée quand le résultat d'une opération <HF>, readline ou glob est testé en tant qu'unique critère d'un while. Cette affectation ne se produit pas en dehors d'un while ou si un quelconque élément additionnel est inclus dans l'expression while.

  • (Mnémonique : le souligné est l'opérande sous-jacent de certaines opérations).

@ARG
@_

  • [GLO] Dans un sous-programme, ce tableau contient la liste d'arguments passée à ce sous-programme. Voir le chapitre 6, Sous-programmes. Un split dans un contexte scalaire s'applique sur ce tableau, mais cet usage est déprécié.

ARGV

  • [GLO] Le handle de fichier spécial qui parcourt les noms de fichiers de la ligne de commande et contenus dans @ARGV. Habituellement, on l'écrit comme le handle de fichier nul dans l'opérateur d'angle <>.

$ARGV

  • [GLO] Contient le nom du fichier courant lorsqu'on lit depuis le handle de fichier ARGV en utilisant les opérateurs <> ou readline.

@ARGV

  • [GLO] Le tableau contenant les arguments de la ligne de commande prévus pour le script. Remarquez que $#ARGV est généralement le nombre d'arguments moins un, puisque $ARGV[0] est le premier argument et non le nom de la commande ; utilisez scalar @ARGV pour le nombre d'arguments du programme. Voir $0 pour le nom du programme.

ARGVOUT

  • [GLO] Ce handle de fichier spécial est utilisé lorsqu'on traite le handle de fichier ARGV avec l'option -i ou la variable $^I. Voir l'option -i dans le chapitre 19, L'interface de ligne de commande.

$b

  • [PKG] Cette variable, sœur de $a, est utilisée dans les comparaisons avec sort. Voir $a et la fonction sort pour les détails.

$BASETIME
$^T

  • [GLO] Le moment où le script a commencé à tourner, en secondes depuis l'origine (le début de 1970, pour les systèmes Unix). Les valeurs renvoyées par les tests de fichier -M, -A et -C sont basées sur ce moment.

$CHILD_ERROR
$?

  • [GLO] Le statut renvoyé par la dernière fermeture de tube, la dernière commande en apostrophe inverse (``) ou les fonctions wait, waitpid ou system. Remarquez qu'il ne s'agit pas simplement du code retour, mais le mot entier de 16-bits du statut renvoyé par les appels système sous-jacents wait(2) ou waitpid(2) (ou leurs équivalents). Ainsi, la valeur de retour du sous-programme se trouve dans l'octet de poids fort, c'est-à-dire, $? >> 8 ; dans l'octet de poids faible, $? & 127 donne quel signal (s'il y en a un) a tué le processus, alors que $? & 128 rapporte si sa disparition a produit un core dump. (Mnémonique : similaire à $? dans sh et sa progéniture).
  • À l'intérieur d'un bloc END, $? contient la valeur qui va être donnée à exit. Vous pouvez modifier $? dans un END pour changer le statut retour du script. Sous VMS, le pragma use vmsish 'status' fait que $? reflète le véritable statut de retour de VMS, au lieu de l'émulation par défaut du statut POSIX.
  • Si la variable h_errno est supportée en C, sa valeur numérique est retournée via $? si l'une des fonctions gethost*() échoue.

$COMPILING
$^C

  • [GLO] La valeur courante de l'argument interne associé à l'option -c, principalement utilisé avec -MO et l'outil perlcc(1) pour laisser le code modifier son comportement lorsqu'il est compilé pour la génération de code. Par exemple, vous pouvez avoir envie d'exécuter AUTOLOAD pendant la phase de compilation, au lieu d'utiliser le chargement différé habituel, de sorte que le code sera généré immédiatement. Voir le chapitre 18.

DATA

  • [PKG] Ce handle de fichier spécial se réfère à tout ce qui suit soit le token __END__ ou le token __DATA__ dans le fichier courant. Le token __END__ ouvre toujours le handle de fichier main::DATA, ainsi il est utilisé dans le programme principal. Le token __DATA__ ouvre le handle de fichier DATA dans n'importe quel paquetage effectif à ce moment. Ainsi différents modules peuvent posséder leur propre handle de fichier DATA, puisqu'ils ont (on le présume) des noms de paquetage différents.

$DEBUGGING
$^D

  • [GLO] La valeur courante des arguments internes, positionnés par l'option -D de la ligne de commande ; voir le chapitre 19 pour les valeurs de bit. (Mnémonique : valeur de l'option -D).

$EFFECTIVE_GROUP_ID
$EGID
$)

  • [GLO] Le gid (group ID) effectif de ce processus. Si vous vous trouvez sur une machine qui accepte que l'on soit membre de plusieurs groupes simultanément, $) donne une liste des groupes concernés, séparés par des espaces. Le premier nombre est celui qui est renvoyé par getgid(2), et les suivants par getgroups(2), l'un d'entre eux pouvant être identique au premier nombre.
    De même, une valeur assignée à $) doit également être une liste de nombres séparés par des espaces. Le premier nombre est utilisé pour positionner le GID effectif, et les autres (s'il y en a) sont passés à l'appel système setgroups(2). Pour obtenir l'effet d'une liste vide pour setgroups, il suffit de répéter le nouveau GID effectif ; par exemple, pour forcer un GID effectif de 5 et une liste vide effective pour setgroups :

     
    Sélectionnez
    $)="5 5";
  • (Mnémonique : les parenthèses sont employées pour regrouper les choses. Le GID effectif est le groupe qui est fermement le bon, si votre script est lancé avec setgid. Il faut donc une parenthèse fermante). Remarque : $<, $>, $( et $) ne peuvent être modifiés que sur des machines qui supportent la routine système set-id correspondante. $( et $) ne peuvent être échangés que sur des machines supportant setregid(2).

$EFFECTIVE_USER_ID
$EUID
$>

  • [GLO] L'UID effectif de ce processus tel que renvoyé par l'appel système geteuid(2). Exemple :
 
Sélectionnez
$< = $>;               # mettre l'uid réel à l'uid effectif
($<, $>) = ($>, $<);   # échanger l'uid réel et l'uid effectif
  • (Mnémonique : il s'agit de l'UID vers lequel vous êtes parvenus si votre script est lancé avec setuid). Remarque : $< et $> ne peuvent être échangés que sur des machines qui supportent setreuid(2). Parfois même, cela ne suffit pas.

%ENV

  • [GLO] Le hachage contenant les variables de l'environnement courant. Modifier une valeur dans %ENV change l'environnement à la fois pour votre processus et pour les processus fils lancés après l'affectation. (On ne peut modifier l'environnement d'un processus parent sur aucun système ressemblant à Unix).

     
    Sélectionnez
    $ENV{PATH} = "/bin:/usr/bin;"
    $ENV{PAGER} = "less";
    $ENV{LESS} = "MQeicsnf";    # nos options favorites pour less(1)
    system "man perl";          # récupère les nouveaux paramètres
  • Pour supprimer quelque chose dans votre environnement, soyez sûr d'utiliser la fonction delete au lieu d'un undef sur la valeur du hachage.

  • Remarquez que les processus qui sont lancés par une entrée de crontab(5) héritent d'un jeu de variables d'environnement particulièrement appauvri. (Si votre programme fonctionne parfaitement depuis la ligne de commande, mais pas avec cron, c'est probablement la cause). Remarquez également que vous devez modifier $ENV{PATH}, $ENV{SHELL}, $ENV{BASH_ENV}, et $ENV{IFS} si votre script est lancé avec setuid. Voir le chapitre 23, Sécurité.

$EVAL_ERROR
$@

  • [GLO] L'exception courante levée ou le message d'erreur de syntaxe Perl de la dernière opération eval. (Mnémonique : quelle est « l'adresse » de la dernière erreur de syntaxe ?) Contrairement à $! ($OS_ERROR), qui est positionné sur un échec, mais pas nettoyé lors d'un succès, on a la garantie que $@ est bien positionné (à une valeur vraie) si le dernier eval a engendré une erreur de compilation ou une exception à l'exécution, mais aussi la garantie que $@ est nettoyé (à une valeur fausse) si aucun de ces problèmes ne survient.
  • Les messages d'avertissement ne sont pas collectés dans cette variable. Cependant, vous pouvez installer une routine destinée à traiter les avertissements en positionnant $SIG{__WARN__} comme décrit plus loin dans cette section.
  • Remarquez que la valeur de $@ peut être un objet exception plutôt qu'une chaîne. Dans ce cas, vous pouvez toujours le traiter comme une chaîne pourvu que l'objet exception ait défini une surcharge de la transformation en chaîne (N.d.T. stringification overload) pour sa classe. Si vous propagez une exception en écrivant :

     
    Sélectionnez
    die if $@;
  • alors un objet exception appellera $@->PROPAGATE pour savoir que faire. (Une chaîne exception ajoutera une ligne « propagée à » à la chaîne.)

$EXCEPTIONS_BEING_CAUGHT
$^S

  • [GLO] Cette variable reflète la situation courante de l'interpréteur, en retournant vrai à l'intérieur d'un eval, faux sinon. Elle est indéfinie si l'analyse de l'unité courante de compilation n'est pas encore finie, ce qui peut être le cas dans les gestionnaires de signaux $SIG{__DIE__} et $SIG{__WARN__}. (Mnémonique : situation de eval.)

$EXECUTABLE_NAME
$^X

  • [GLO] Le nom avec lequel le binaire perl lui-même a été exécuté, provient de argv[0] en C.

@EXPORT

  • [PKG] Ce tableau est consulté par la méthode import du module Exporter pour trouver la liste des variables et sous-programmes d'autres paquetages qui doivent être exportés par défaut quand le module est utilisé (avec use) ou lorsqu'on emploie l'option d'importation :DEFAULT. Il n'est pas exempt des complaintes de use strict, ainsi il doit être déclaré avec our ou pleinement qualifié avec le nom du paquetage si vous avez activé ce pragma. De toute façon, toutes les variables qui commencent par « EXPORT » sont exemptes des avertissements comme quoi elles ne sont utilisées qu'une seule fois. Voir le chapitre 11, Modules.

@EXPORT_OK

  • [PKG] Ce tableau est consulté par la méthode import du module Exporter pour déterminer si une requête d'importation est légale. Il n'est pas exempt des complaintes de use strict. Voir le chapitre 11.

%EXPORT_TAGS

  • [PKG] Ce hachage est consulté par la méthode import du module Exporter lorsqu'on requiert un symbole d'importation débutant par deux points, comme dans use POSIX ":queue". Les clefs sont les tags commençant par deux points, mais sans les deux points (comme sys_wait_h). Les valeurs doivent être des références à des tableaux contenant les symboles à importer lorsqu'on requiert ce tag ; toutes les valeurs du hachage doivent également apparaître soit dans @EXPORT, soit dans @EXPORT_OK. Ce hachage n'est pas exempt des complaintes de use strict. Voir le chapitre 11.

$EXTENDED_OS_ERROR
$^E

  • [GLO] Information d'erreur spécifique au système d'exploitation courant. Sous Unix, $^E est identique à $! ($OS_ERROR), mais elle diffère sous OS/2, VMS, les systèmes Microsoft et MacPerl. Consultez les informations sur votre portage pour les spécificités. Les mises en garde mentionnées dans la description de $! s'appliquent aussi à $^E en général . (Mnémonique : explication étendue d'erreur.)

@F

  • [PKG] Le tableau dans lequel les lignes d'entrée sont éclatées quand la ligne de commande comporte l'option -a est donnée. Si l'option -a n'est pas utilisée, ce tableau n'a aucune signification particulière (ce tableau n'est en fait que @main::F et non dans tous les paquetages à la fois).

%FIELDS

  • [NON, PKG] Ce hachage est utilisé en interne par le pragma use fields pour déterminer les champs légaux courants dans un objet hachage. Voir use fields, use base et Déclarations de champ avec use fields au chapitre 12.

format_formfeed HANDLE EXPR
$FORMAT_FORMFEED
$^L

  • [GLO] Ce qu'une fonction write génère implicitement pour effectuer un saut de page avant d'émettre un en-tête de page. "\f" par défaut.

format_lines_left HANDLE EXPR
$FORMAT_LINES_LEFT
$-

  • [AHF] Le nombre de lignes restantes dans la page du canal de sortie actuellement sélectionné, pour une utilisation avec la déclaration format et la fonction write. (Mnémonique : lines_on_pages lines_printed.)

format_lines_per_page HANDLE EXPR
$FORMAT_LINES_PER_PAGE
$=

  • [AHF] La longueur de la page courante (lignes imprimables) du canal de sortie actuellement sélectionné, pour une utilisation avec format et write. 60 par défaut. (Mnémonique : est composé des lignes horizontales.)

format_line_break_characters HANDLE EXPR
$FORMAT_LINE_BREAK_CHARACTERS
$:

  • [GLO] Le jeu de caractères courant d'après lequel une chaîne peut être scindée pour remplir les champs de continuation (commençant par ^) dans un format. " \n-" par défaut, pour couper sur l'espace ou le tiret. (Mnémonique : un « deux-points » en poésie fait partie d'une ligne. Maintenant il ne vous reste plus qu'à vous rappeler du procédé mnémonique...)

format_name HANDLE EXPR
$FORMAT_NAME
$~

  • [AHF] Le nom du format de rapport courant pour le canal de sortie actuellement sélectionné. Le nom du handle du fichier par défaut. (Mnémonique : cette variable tourne après $^.)

format_page_number HANDLE EXPR
$FORMAT_PAGE_NUMBER
$%

  • [AHF] Le numéro de page courant du canal de sortie actuellement sélectionné, pour une utilisation avec format et write. (Mnémonique : % est le registre de numéro de page dans troff(1). Quoi, vous ne savez pas ce qu'est troff ?)

format_top_name HANDLE EXPR
$FORMAT_TOP_NAME
$^

  • [AHF] Le nom du format d'en-tête de page courant pour le canal de sortie actuellement sélectionné. Le nom du handle de fichier auquel est ajouté _TOP par défaut. (Mnémonique : pointe vers le haut de la page.)

$^H

  • [NON, LEX] Cette variable contient les bits de statut du contexte lexical (autrement dit, des indications) pour le parseur Perl. Cette variable est strictement réservée à une utilisation interne. Sa disponibilité, son comportement et son contenu sont sujets à modifications sans préavis. Si vous y touchez, vous périrez indubitablement d'une mort horrible causée par une détestable maladie tropicale inconnue de la science. (Mnémonique : nous ne vous donnerons aucune indication.)

%^H

  • [NON, LEX] Le hachage %^H fournit la même sémantique de contexte lexical que $^H, le rendant utile pour l'implémentation des pragmas de contexte lexical. Lisez les affreuses mises en garde énoncées pour $^H, et ajoutez-y le fait que cette variable est encore expérimentale.

%INC

  • [GLO] Le hachage contenant les entrées de noms de fichiers pour chaque fichier Perl chargé via do FICHIER, require ou use. La clef est le nom du fichier spécifié, et la valeur est l'endroit où le fichier a été véritablement trouvé. L'opérateur require utilise ce tableau pour déterminer si un fichier donné a déjà été chargé. Par exemple :
 
Sélectionnez
% perl -MLWP::Simple -le 'print $INC{LWP/Simple.pm}'
/usr/local/lib/perl/5.6.0/lib/site_perl/LWP/Simple.pm

@INC

 
Sélectionnez
/usr/local/lib/perl5/5.6.0/i386-linux
/usr/local/lib/perl5/5.6.0
/usr/local/lib/perl5/site_perl/5.6.0/i386-linux /usr/local/lib/perl5/site_perl/5.6.0 /usr/local/lib/perl5/site_perl/5.00552/i386-linux
/usr/local/lib/perl5/site_perl/5.00552 /usr/local/lib/perl5/site_perl/5.005/i386-linux /usr/local/lib/perl5/site_perl/5.005
/usr/local/lib/perl5/site_perl
  • [GLO] Le tableau contenant la liste des répertoires où les modules Perl peuvent être trouvés par do FICHIER, require ou use. Initialement, il se compose des arguments de n'importe quelle option -I de la ligne de commande et des répertoires de la variable d'environnement PERL5LIB, suivis par les bibliothèques par défaut de Perl, comme :
  • suivies par « . », qui représente le répertoire courant. Si vous avez besoin de modifier cette liste depuis votre programme, essayer le pragma use lib, qui non seulement modifie la variable durant la compilation, mais qui fait également des ajouts dans tous les répertoires dépendant de l'architecture (comme ceux qui contiennent les bibliothèques partagées utilisées par les modules XS) :
 
Sélectionnez
use lib "/monchemin/lib/"; use UnModule;

$INPLACE_EDIT
$^I

  • [GLO] La valeur courante de l'extension d'édition sur place. Employez undef pour désactiver l'édition sur place. Vous pouvez utiliser ceci à l'intérieur de votre programme pour obtenir le même comportement qu'avec l'option -i. Par exemple, pour produire l'équivalent de cette commande :

     
    Sélectionnez
    % perl -i.orig -pe 's/machin/truc/g' *.c
  • vous pouvez utiliser le code suivant dans votre programme :

     
    Sélectionnez
    local $^I = '.orig';
    local @ARGV = glob("*.c");
    while (<>) {
        s/machin/truc/g;
        print;
    }
  • (Mnémonique : la valeur de l'option -i.)

$INPUT_LINE_NUMBER
$NR
$.

  • [GLO] Le numéro de l'enregistrement courant (généralement le numéro de ligne) pour le dernier handle de fichier dans lequel vous avez lu (ou sur lequel vous avez appelé seek ou tell). La valeur peut être différente de la ligne physique actuelle, selon la définition à ce moment de ce qu'est une « ligne » — voir $/ ($INPUT_RECORD_NUMBER) pour la manière de choisir cette définition). Un close explicite sur un handle de fichier réinitialise à zéro le numéro de ligne. Comme <> n'effectue jamais de close explicite, les numéros de ligne augmentent en parcourant les fichiers ARGV (mais voyez les exemples de eof). La mise en local de $. a également pour effet de mettre en local la notion que Perl a du « dernier handle de fichier lu ». (Mnémonique : de nombreux programmes utilisent « . » pour le numéro de ligne courant.)

$INPUT_RECORD_SEPARATOR
$RS
$/

  • [GLO] Le séparateur d'enregistrement en entrée, le caractère « saut de ligne » par défaut, celui qui est consulté par la fonction readline, l'opérateur <HF>, et la fonction chomp. Il se comporte comme la variable RS de awk, et, s'il contient la chaîne nulle, traite une ou plusieurs lignes blanches comme des délimiteurs d'enregistrements. (Mais une ligne vide ne doit contenir aucun espace caché ou aucune tabulation). Vous pouvez affecter à cette variable une chaîne de plusieurs caractères pour correspondre à un séparateur sur plusieurs caractères, mais vous ne pouvez pas lui affecter un motif — il faut bien que awk soit meilleur dans un domaine.
  • Remarquez que le fait d'affecter " à $/ signifie quelque chose de sensiblement différent que de lui affecter "", si le fichier contient des lignes blanches consécutives. "" traitera deux lignes blanches consécutives ou plus comme une seule ligne blanche. "\n\n" signifie que Perl suppose aveuglément qu'une troisième ligne appartient au paragraphe suivant.
  • Si l'on rend carrément $/ indéfini, la prochaine opération de lecture de ligne avalera le reste du fichier dans une seule valeur scalaire :

     
    Sélectionnez
    undef $/;       # enclenche le mode "cul-sec"
    $_ = <HF>;      # maintenant le fichier entier est ici
    s/\n[ \t]+/ /g; # aplatit les lignes indentées
  • Si vous utilisez la construction while (<>) pour accéder au handle de fichier ARGV alors que $/ vaut undef, chaque lecture prend le fichier suivant :

     
    Sélectionnez
    undef $/;
    while (<>) {  # $_ contient le prochain fichier dans sa totalité
        ...
    }
  • Bien que nous ayons employé undef ci-dessus, il est plus sûr de rendre $/ indéfini en utilisant local :

     
    Sélectionnez
    {
        local $/;
        $_ = <HF>;
    }
  • Affecter à $/ une référence soit à un entier, soit à un scalaire contenant un entier, soit à un scalaire convertible en entier, fera que les opérations readline et <HF> liront des enregistrements de taille fixe (avec la taille maximale d'enregistrement valant l'entier référencé) au lieu d'un enregistrement de taille variable terminé par une chaîne particulière. Ainsi, ceci :

     
    Sélectionnez
    $/ = 32768; # ou \"32768" ou \$var_scalaire_contenant_32768 open(FICHIER, $monfichier);
    $enregistrement = <FICHIER>;
  • lira un enregistrement d'au plus 32768 octets depuis le handle de FICHIER. Si vous ne lisez pas un fichier structuré par enregistrement (N.d.T. record-oriented file) (ou si votre système d'exploitation ne connaît pas les fichiers structurés par enregistrement), alors vous aurez vraisemblablement un morceau de données à chaque lecture. Si un enregistrement est plus volumineux que la taille que vous avez fixée, vous recevrez l'enregistrement découpé en plusieurs tranches. Le mode par « enregistrement » ne se marie bien avec le mode par ligne que sur les systèmes où les entrées/sorties standards fournissent une fonction read(3) ; VMS est une exception notoire.

  • Un appel à chomp lorsque $/ est positionnée sur le mode par enregistrement — ou lorsqu'elle n'est pas définie — n'a aucun effet. Voir aussi les options de la ligne de commande -0 (le chiffre) et -l (la lettre) dans le chapitre 19. (Mnémonique : / est utilisé pour séparer les lignes lorsque l'on cite de la poésie.)

@ISA

  • [PKG] Ce tableau contient les noms des autres paquetages dans lesquels il faut rechercher une méthode qui n'a pu être trouvée dans le paquetage courant. Autrement dit, il contient les classes de base du paquetage. Le pragma use base positionne ceci implicitement. Il n'est pas exempt des complaintes de use strict. Voir le chapitre 12.

@LAST_MATCH_END
@+

  • [DYN,LEC] Ce tableau contient les positions des fins des sous-éléments de la dernière recherche de correspondance ayant réussi dans le contexte dynamique actuellement actif. $-[0] est la position à la fin de la correspondance entière. Il s'agit de la même valeur que celle retournée par la fonction pos lorsqu'on l'appelle avec comme paramètre la variable sur laquelle s'est faite la recherche de correspondance. Lorsque nous parlons de « la position de la fin », nous voulons réellement dire la position du premier caractère qui suit la fin de ce qui a correspondu, ainsi nous pouvons soustraire les positions de début aux positions de fin pour obtenir la longueur. Le nième élément de ce tableau contient la position du nième élément de la correspondance, ainsi $+[1] est la position où finit $1, $+[2] la position où $2 finit, etc. Vous pouvez utiliser $#+ pour déterminer combien d'éléments ont réussi à correspondre dans la dernière recherche. Voir aussi @- (@LAST_MATCH_START).
  • Après une recherche de correspondance réussie sur une variable $var :

    • $' est identique à substr($var, 0, $-[0])
    • $& est identique à substr($var, $-[0], $+[0] -$-[0])
    • $' est identique à substr($var, $+[0])
    • $1 est identique à substr($var, $-[1], $+[1] -$-[1])
    • $2 est identique à substr($var, $-[2], $+[2] -$-[2])
    • $3 est identique à substr($var, $-[3], $+[3] -$-[3]), etc.

@LAST_MATCH_START
@-

  • [DYN,LEC] Ce tableau contient les positions des débuts des sous-éléments de la dernière recherche de correspondance ayant réussi dans le contexte dynamique actif. $-[0] est la position au début de la correspondance entière. Le nième élément de ce tableau contient la position du nième élément de la correspondance, ainsi $-[1] est la position où débute $1, $-[2] la position où $2 débute, etc. Vous pouvez utiliser $#- pour déterminer combien d'éléments ont réussi à correspondre dans la dernière recherche. Voir aussi @+ (@LAST_MATCH_END).

$LAST_PAREN_MATCH
$+

  • [DYN, LEC] Cette variable renvoie ce qu'a trouvé la dernière recherche de parenthèse dans le contexte dynamique actuellement actif. C'est utile si l'on ne sait pas (ou si l'on ne s'en préoccupe pas) lequel des motifs parmi une alternative a été trouvé. (Mnémonique : Soyez positifs et regardez droit devant.) Exemple :
 
Sélectionnez
$rev = $+ if /Version: (.*)|Revision: (.*)/;

$LAST_REGEXP_CODE_RESULT
$^R

  • [DYN] Cette variable contient le résultat du dernier morceau de code exécuté au sein d'une recherche de motifs réussie construite avec (?{ CODE }). $^R vous donne un moyen d'exécuter du code et d'en retenir le résultat pour l'utiliser plus tard dans le motif, ou même encore après.
  • Comme le moteur d'expressions régulières de Perl se déplace tout au long du motif, il peut rencontrer de multiples expressions (?{ CODE }). Lorsque cela arrive, il retient chaque valeur de $^R de manière à ce qu'il puisse restaurer l'ancienne valeur de $^R si plus tard il doit reculer avant l'expression. En d'autres termes, $^R possède un contexte dynamique au sein du motif, un peu comme $1 et ses amis.
  • Ainsi, $^R n'est pas juste le résultat du dernier morceau de code exécuté au sein d'un motif. C'est le résultat du dernier morceau de code qui a conduit au succès de la correspondance. Un corollaire est que si la correspondance a échoué, $^R reprendra la valeur qu'elle avait avant la correspondance.
  • Si le motif (?{ CODE }) est employé directement comme la condition d'un sous-motif (?(CONDITION)SI_VRAI|SI_FAUX), $^R n'est pas valorisée.

$LIST_SEPARATOR
$"

  • [GLO] Lorsqu'un tableau ou une tranche est interpolé dans une chaîne entre guillemets (ou un équivalent), cette variable indique la chaîne à mettre entre les éléments individuels. Un espace par défaut. (Mnémonique : on peut espérer que c'est évident.)

$^M

  • [GLO] Par défaut, on ne peut pas intercepter un dépassement de mémoire. Toutefois, si votre perl a été compilé pour bénéficier de $^M, vous pouvez l'utiliser comme un espace mémoire en cas d'urgence. Si votre Perl est compilé avec DPERL_EMERGENCY_SBRK et utilise le malloc de Perl, alors :

     
    Sélectionnez
    $^M = 'a' x(1 < < 16);
  • allouera un tampon de 64K en cas d'urgence. Voir le fichier INSTALL dans le répertoire du code source de la distribution Perl pour les informations sur la manière d'activer cette option.

  • En guise d'effet dissuasif pour l'emploi de cette fonctionnalité avancée, il n'y a pas de nom long avec use English pour cette variable (et nous ne vous dirons pas quel est le procédé mnémonique).

$MATCH
$&

  • [DYN, LEC] La chaîne trouvée par la dernière recherche de motif dans le contexte dynamique actuellement actif. (Mnémonique : comme & dans certains éditeurs.)

$OLD_PERL_VERSION
$]

  • [GLO] Renvoie la version + niveau_de_patch/1000. On peut l'utiliser pour déterminer au début du script si l'interpréteur Perl qui exécute le script est dans une plage de versions correcte. (Mnémonique : cette version de Perl est-elle dans le bon intervalle ? L'intervalle mathématique étant représenté par un crochet). Exemple :

     
    Sélectionnez
    warn "Pas de somme de contrôle !\n" if $] < 3.019;
    die "Exige la disponibilité du prototypage\n" if $] < 5.003;
  • Voir aussi la documentation de use VERSION et require VERSION pour un moyen convenable d'échouer si l'interpréteur Perl est trop ancien. Voir $^V pour une représentation UTF-8 plus flexible de la version de Perl.

$OSNAME
$^O

  • [GLO] Cette variable contient le nom de la plate-forme (généralement du système d'exploitation) pour laquelle le binaire Perl courant a été compilé. Elle sert surtout à ne pas appeler le module Config.

$OS_ERROR
$ERRNO
$!

  • [GLO] Dans un contexte numérique, donne la valeur courante de la dernière erreur d'appel système, avec toutes les restrictions d'usage. (Ce qui signifie qu'il vaut mieux ne pas attendre grand-chose de la valeur de $! à moins qu'une erreur renvoyée n'indique spécifiquement une erreur système). Dans un contexte de chaîne, $! donne la chaîne du message d'erreur correspondant. Vous pouvez assigner un numéro d'erreur à $! si, par exemple, vous voulez que $! renvoie la chaîne correspondant à cette erreur particulière, ou si vous voulez positionner la valeur de sortie de die. Voir aussi le module Errno au chapitre 32. (Mnémonique : j'ai entendu qu'on venait de s'exclamer ?)

%OS_ERROR
%ERRNO
%!

  • [GLO] Ce hachage n'est défini que si vous avez chargé le module standard Errno décrit au chapitre 32. Une fois ceci fait, vous pouvez accéder à %! en utilisant une chaîne d'erreur particulière, et sa valeur n'est vraie que s'il s'agit de l'erreur courante. Par exemple, $!{ENOENT} n'est vraie que si la variable C errno vaut à ce moment la valeur de ENOENT dans le #define en C. C'est un moyen pratique d'accéder aux symboles spécifiques d'un fabricant.

     
    Sélectionnez
    autoflush HANDLE EXPR
    $OUTPUT_AUTOFLUSH $AUTOFLUSH
    $|
  • [AHF] Si elle est positionnée à vrai, cette variable force un tampon à être vidé après chaque print, printf et write sur le handle de sortie actuellement sélectionné. (C'est ce que nous appelons vidage du tampon de commande. Contrairement à la croyance populaire, positionner cette variable ne désactive pas le vidage du tampon.) Elle vaut faux, par défaut, ce qui signifie sur de nombreux systèmes que STDOUT est vidé ligne par ligne si la sortie s'effectue sur terminal, et vidé bloc par bloc si ce n'est pas le cas, même dans les tubes et les sockets. Positionner cette variable est utile lorsque vous envoyez la sortie vers un tube, comme lorsque vous lancez un script Perl sous rsh(1) et que vous voulez en voir la sortie en temps réel. Si vous avez des données en attente d'être vidées dans le tampon du handle de fichier actuellement sélectionné lorsque cette variable est positionnée à vrai, ce tampon sera immédiatement vidé par effet de bord de l'affectation. Voir la forme à un seul argument de select pour des exemples de contrôle du tampon sur les handles de fichier autres que STDOUT. (Mnémonique : quand vous voulez que vos tubes soient fumants.)

  • Cette variable n'a aucun effet sur le vidage du tampon d'entrée ; pour ceci, voir getc dans le chapitre 29 ou l'exemple dans le module POSIX au chapitre 32.

$OUTPUT_FIELD_SEPARATOR
$OFS
$,

  • [GLO] Le séparateur de champs en sortie (le limitateur, en fait) pour print. Normalement, print affiche simplement la liste d'éléments que vous spécifiez sans rien entre eux. Affecter cette variable fera spécifier à la variable OFS de awk ce qui doit être affiché entre les champs. (Mnémonique : ce qui est affiché quand il y a une « , » dans l'instruction print.)

$OUTPUT_RECORD_SEPARATOR
$ORS
$\

  • [GLO] Le séparateur d'enregistrement en sortie (le délimiteur, en fait) pour print. Normalement, print affiche simplement les champs séparés par des virgules que vous avez spécifiés, sans saut de ligne final, ni séparateur d'enregistrements. Affectez cette variable, comme vous auriez affecté la variable ORS de awk, pour spécifier ce qui est affiché à la fin du print. (Mnémonique : vous assignez $\ au lieu d'ajouter "\n" à la fin du print. De même, cette variable ressemble à /, mais pour ce que Perl « retourne ».) Voir aussi l'option de la ligne de commande -l (pour « ligne ») dans le chapitre 19

%OVERLOAD

  • [NON, PKG] Ces entrées de hachage sont positionnées en interne grâce au pragma use overload pour implémenter la surcharge d'opérateur pour les objets de la classe du paquetage courant. Voir le chapitre 13, Surcharge.

$PERLDB
$^P

  • [NON, GLO] La variable interne pour activer le débogueur Perl (perl -d).

$PERL_VERSION
$^V

  • [GLO] La révision, la version, et la sous-version de l'interpréteur Perl, représentées comme une « chaîne de version » binaire. Les v-chaînes n'ont généralement pas de valeur numérique, mais cette variable est doublement valuée, et elle a une valeur numérique équivalente à l'ancienne variable $] ; c'est-à-dire un nombre à virgule valant révision + version/1000 + sous-version/1000000. La valeur de la chaîne est composée des caractères UTF8 : chr($revision) . chr($version) . chr($sous_version). Cela signifie que $^V n'est pas affichable. Pour l'afficher, vous devez écrire :

     
    Sélectionnez
    printf "%vd", $^V;
  • Dans les bons côtés, cela veut également dire que la comparaison normale de chaînes peut être utilisée pour déterminer si l'interpréteur Perl qui exécute votre script est dans une plage de versions correcte. (Ceci s'applique à n'importe quelle version numérique représentée avec des v-chaînes, pas seulement celles de Perl). Exemple :

     
    Sélectionnez
    warn "Pas de déclarations avec 'our'\n" if $^V lt v5.6;
  • Voir la documentation de use VERSION et require VERSION pour un moyen convenable d'échouer si l'interpréteur Perl est plus ancien que ce que vous espériez. Voir aussi $] pour la représentation originelle de la version de Perl.

$POSTMATCH
$'

  • [DYN, LEC] La chaîne qui suit tout ce qui a été trouvé par la dernière recherche de motif réussie dans le contexte dynamique actuellement actif. (Mnémonique : ' suit souvent une chaîne protégée.) Exemple :

     
    Sélectionnez
    $_ = 'abcdefghi';
    /def/;
    print "$`:$&:$\n";  # affiche abc:def:ghi
  • À cause du contexte dynamique, Perl ne peut pas savoir quel motif aura besoin de sauvegarder ses résultats dans ces variables, ainsi mentionner $ ou $' n'importe où dans le programme entraîne une pénalisation dans les performances pour toutes les recherches de motif tout au long du programme. Ce n'est pas un gros problème dans les programmes courts, mais vous voudrez probablement éviter cette paire de variables si vous écrivez le code d'un module réutilisable. L'exemple ci-dessus peut être réécrit de manière équivalente, mais sans le problème de performances globales, ainsi :
 
Sélectionnez
$_ = 'abcdefghi';
/(.*?)(def)(.*)/s    # /s au cas où $1 contiendrait des sauts de ligne
print "$1:$2:$3\n";  # affiche abc:def:ghi

$PREMATCH
$`

  • [DYN, LEC] La chaîne qui précède tout ce qui a été trouvé par la dernière recherche de motif réussie dans le contexte dynamique actuellement actif.
  • (Mnémonique : ` précède souvent une chaîne protégée.) Voir la remarque sur les performances de $' ci-dessus.

$PROCESS_ID
$PID
$$

  • [GLO] Le numéro de processus (PID) du Perl en train d'exécuter ce script. Cette variable est automatiquement mise à jour dans un fork. En fait, vous pouvez même modifier $$ vous-même ; ceci ne changera pas votre PID de toute façon. Ce serait un joli coup. (Mnémonique : comme pour les shells divers et variés).
  • Vous devez faire attention de ne pas utiliser la variable $$ n'importe où elle pourrait être malencontreusement interprétée comme une déréférence : $$alphanum. Dans ce cas, écrivez ${$}alphanum pour distinguer de ${$alphanum}.

$PROGRAM_NAME
$0

  • [GLO] Contient le nom du fichier contenant le script Perl en train d'être exécuté. L'affectation d'une valeur à $0 est magique : elle tente de modifier la zone d'arguments que voit le programme ps(1). Ceci est plus utile pour indiquer l'état courant du programme que pour cacher le programme en train de tourner. Mais cela ne fonctionne pas sur tous les systèmes. (Mnémonique : pareil que dans sh, ksh, bash, etc.)

$REAL_GROUP_ID
$GID
$(

  • [GLO] Le GID (groupe ID) réel de ce processus. Si vous vous trouvez sur une machine qui accepte que l'on soit membre de plusieurs groupes simultanément, $( donne une liste des groupes concernés, séparés par des espaces. Le premier nombre est celui qui est renvoyé par getgid(2), et les suivants par getgroups(2), l'un d'entre eux pouvant être identique au premier nombre.
  • De toute façon, une valeur assignée à $( doit être un seul et unique nombre utilisé pour positionner le GID. Ainsi la valeur donnée par $( ne doit pas être réaffectée à $( sans la forcer à être numérique, comme en lui ajoutant zéro. Ceci parce que vous ne pouvez avoir qu'un seul groupe réel. Voir plutôt $) ($EFFECTIVE_GROUP_ID), qui vous permet d'affecter plusieurs groupes effectifs.
  • (Mnémonique : les parenthèses sont employées pour regrouper les choses. Le GID réel est le groupe que vous laissez ouvert derrière vous, si votre script est lancé avec setgid. Il faut donc une parenthèse ouvrante.)

$REAL_USER_ID
$UID
$<

  • [GLO] L'UID réel de ce processus tel que renvoyé par l'appel système geteuid(2). Savoir si vous pouvez le changer et comment le faire est dépendant de la bonne volonté de l'implémentation sur votre système — voir les exemples dans $> ($EFFECTIVE_USER_ID). (Mnémonique : il s'agit de l'UID d'où vous provenez si votre script est lancé avec setuid.)

%SIG

  • [GLO] Le hachage utilisé pour installer les gestionnaires de divers signaux. (Voir la section Signaux dans le chapitre 16, Communication interprocessus). Par exemple :

     
    Sélectionnez
    sub gestionnaire {
        my $sig = shift; # le 1er argument est le nom du signal
        syswrite STDERR, "SIG$sig détecté--on quitte\n";
                          # Évitez les entrées/sorties standards dans les
                          # gestionnaires asynchrones pour supprimer le
                          # core dump). (Même cette concaténation de chaîne
                          # est risquée).
               close LOG; # Ceci appelle une entrée/sortie standard, ainsi
                          # il peut y avoir quand même un core dump !
                  exit 1; #, Mais puisque l'on quitte le programme,
                          # il n'y a pas de mal à essayer.
    }
    $SIG{INT} = \&gestionnaire;
    $SIG{QUIT) = \&gestionnaire;
    ...
    $SIG{INT} = 'DEFAULT';  # rétablir l'action par défaut
    $SIG{QUIT} = 'IGNORE';  # ignorer SIGQUIT
  • Le hachage %SIG contient des valeurs indéfinies correspondant aux signaux pour lesquels aucun gestionnaire n'a été affecté. Un gestionnaire peut être spécifié comme une référence de sous-programme ou comme une chaîne. Une chaîne dont la valeur n'est pas l'une des deux actions spéciales « DEFAULT » ou « IGNORE » est le nom d'une fonction, qui, si elle n'est pas qualifiée par un paquetage, est interprétée comme faisant partie du paquetage main. Voici quelques exemples :

     
    Sélectionnez
    $SIG{PIPE} = "Plombier";     # OK, on suppose qu'il s'agit de
                                 # main::plombier
    $SIG{PIPE} = \&Plombier;     # bien, on utilise Plombier dans
                                 # le paquetage courant
  • Certaines routines internes peuvent également être installées avec le hachage %SIG. La routine indiquée par $SIG{__WARN__} est appelée quand un message d'avertissement va être affiché. Le message est passé en premier argument. La présence d'une routine __WARN__ provoque la suppression de l'affichage normal des messages d'avertissements vers STDERR. Vous pouvez vous en servir pour sauvegarder ces messages dans une variable ou pour transformer les avertissements en erreurs fatales, comme ceci :

     
    Sélectionnez
    local $SIG{__WARN__} = sub { die $_[0] };
    eval $programmette;
  • C'est équivalent à :

     
    Sélectionnez
    use warnings qw/FATAL all/;
    eval $programmette
  • excepté le fait que le premier code a un contexte dynamique alors que le second a un contexte lexical. La routine indiquée par $SIG{__DIE__} offre un moyen de changer une exception batracienne en exception princière avec un baiser magique, ce qui souvent ne fonctionne pas. La meilleure utilisation est l'exécution de choses de dernière minute lorsqu'un programme est sur le point de mourir suite à une exception non interceptée. Vous ne sauverez pas votre peau ainsi, mais vous aurez le droit de formuler une dernière volonté.

  • Le message d'exception est passé en premier argument. Quand une routine __DIE__ revient, le traitement de l'exception continue comme il l'aurait fait en l'absence de l'interception, à moins que la routine d'interception ne quitte elle-même par un goto, une sortie de boucle ou un die. Le gestionnaire de __DIE__ est explicitement désactivé pendant l'appel, afin que vous puissiez vous-même appeler alors le véritable die depuis un gestionnaire de __DIE__. (Si ce n'était pas le cas, le gestionnaire s'appellerait lui-même indéfiniment.) Le gestionnaire pour $SIG{__WARN__} procède de la même façon.

  • Seul le programme principal doit positionner $SIG{__DIE__}, pas le module. Ceci, car actuellement, même les exceptions qui sont interceptées continuent de déclencher un gestionnaire de $SIG{__DIE__}. Ceci est fortement déconseillé, car vous pourriez briser d'innocents modules qui ne s'attendaient pas à ce que les exceptions qu'ils prévoyaient soient altérées. Utilisez cette fonctionnalité uniquement en dernier ressort, et si vous le devez, mettez toujours devant un local pour limiter la durée du danger.

  • N'essayez pas de construire un mécanisme de gestion de signal à partir de cette fonctionnalité. Utilisez plutôt eval {} pour intercepter les exceptions.

STDERR

  • [GLO] Le handle de fichier spécial pour la sortie d'erreur standard dans n'importe quel paquetage.

STDIN

  • [GLO] Le handle de fichier spécial pour l'entrée standard dans n'importe quel paquetage.

STDOUT

  • [GLO] Le handle de fichier spécial pour la sortie standard dans n'importe quel paquetage.

$SUBSCRIPT_SEPARATOR
$SUBSEP
$;

  • [GLO] Le séparateur d'indices pour l'émulation de hachage multidimensionnels. Si vous vous référez à un élément de hachage comme :

     
    Sélectionnez
    $machin{$a,$b,$c}
  • cela veut vraiment dire :

     
    Sélectionnez
    $machin{join($;, $a, $b, $c)}
  • Mais ne mettez pas :

     
    Sélectionnez
    @machin{$a,$b,$c} # une tranche de tableau -remarquez le @
  • qui signifie :

     
    Sélectionnez
    ($m{$a},$machin{$b},$machin{$c})
  • La valeur par défaut est "\034", la même que SUBSEP dans awk. Remarquez que si vos clefs contiennent des données binaires, il ne peut exister de valeur sûre pour $;.

  • (Mnémonique : virgule — le séparateur d'indices syntaxique — est un point-virgule. Oui, je sais, c'est un peu faible, mais $, est déjà prise pour quelque chose de plus important.)

  • Bien que nous n'ayons pas découragé cette fonctionnalité, vous devez plutôt envisager d'utiliser maintenant de « véritables » hachages multidimensionnels, comme $machin{$a}{$b}{$c} au lieu de $machin{$a,$b,$c}. Les simulations de hachages multidimensionnels peuvent cependant être plus faciles à trier et sont plus à même d'utiliser les fichiers DBM.

$SYSTEM_FD_MAX
$^F

  • [GLO] Le descripteur de fichier « système » maximum, généralement 2. Les descripteurs de fichiers systèmes sont passés aux nouveaux programmes durant un exec, alors que les descripteurs supérieurs ne le sont pas. De plus, pendant un open, les descripteurs de fichiers systèmes sont préservés même si le open échoue. (Les descripteurs de fichiers ordinaires sont fermés avant que l'ouverture ne soit tentée et le restent si elle échoue.) Remarquez que le statut de close-on-exec d'un descripteur de fichier se décide d'après la valeur de $^F au moment du open, et non au moment du exec. Évitez ceci en affectant à $^F une valeur qui explose les compteurs :
 
Sélectionnez
{
    local $^F = 10_000;
    pipe(SALUT, CAVA) or die "pipe a échoué : $!";
}

$VERSION

  • [PKG] Cette variable est accessible à tout moment où une version minimale acceptable d'un module est spécifiée, comme dans use UnModule 2.5. Si $UNMODULE::VERSION est inférieure, une exception est levée. Techniquement, c'est la méthode UNIVERSAL->VERSION qui inspecte cette variable, vous pouvez donc définir votre propre fonction VERSION dans le paquetage courant si vous voulez autre chose que le comportement par défaut. Voir le chapitre 12.

$WARNING
$^W

  • [GLO] La valeur booléenne courante de l'option globale d'avertissement (à ne pas confondre avec l'option globale d'asservissement, à propos de laquelle nous avons entendu de nombreux avertissements globaux). Voir aussi le pragma use warnings au chapitre 31, Modules de pragma, et les options de la ligne de commande -W et -X pour les avertissements dans un contexte lexical, qui ne sont pas affectés par cette variable. (Mnémonique : la valeur est liée à l'option -w.)

${^WARNING_BITS}

${^WIDE_SYSTEM_CALLS}

  • [GLO} L'argument global qui permet à tous les appels systèmes effectués par Perl d'utiliser les API wide-characters natives du système, si elles sont disponibles. Il peut également être activé depuis la ligne de commande en utilisant l'option -C. La valeur initiale est généralement 0 pour assurer la compatibilité avec les versions de Perl antérieures à la 5.6, mais il peut être automatiquement mis à 1 par Perl si le système fournit une valeur par défaut modifiable par l'utilisateur (comme via $ENV{LC_TYPE}). Le pragma use bytes annule les effets de cet argument dans le contexte lexical courant.

Et maintenant, attachez vos ceintures pour un grand chapitre...

29. Fonctions

Ce chapitre décrit les fonctions intrinsèques de Perl par ordre alphabétique(198) par souci pratique de référence. Chaque description de fonction commence par un bref résumé de la syntaxe pour cette fonction. Les noms de paramètre en CAPITALES OBLIQUES indiquent en fait les emplacements pour des expressions ; le texte qui suit le résumé de la syntaxe décrit ensuite la sémantique de ces arguments lorsqu'on les fournit (ou qu'on les omet).

Vous pouvez considérer que les fonctions sont des termes dans une expression au même titre que les littéraux et les variables. Ou bien, vous pouvez considérer qu'il s'agit d'opérateurs préfixes, qui traitent les arguments qui les suivent. D'ailleurs, nous utilisons le mot opérateur la plupart du temps.

Certains de ces opérateurs, euh, fonctions, prennent comme argument une LISTE. Les éléments de la LISTE doivent être séparés par des virgules (ou par =>, qui est juste une drôle de variété de virgule). Les éléments de la LISTE sont évalués dans un contexte de liste, ainsi chaque élément renvoie, soit un scalaire, soit une valeur de liste, selon sa sensibilité au contexte de liste. Chaque valeur renvoyée, que ce soit un scalaire ou une liste, sera interpolée comme étant un composant de la séquence entière de valeurs scalaires. C'est-à-dire que les listes sont mises à plat dans une seule liste. Du point de vue de la fonction qui reçoit les arguments, l'argument global LISTE est toujours une valeur de liste à une dimension. (Pour interpoler un tableau comme un élément unique, vous devez explicitement créer et interpoler à la place une référence à ce tableau.)

Les fonctions prédéfinies de Perl peuvent être utilisées avec ou sans parenthèses encadrant les arguments ; dans ce chapitre les résumés de syntaxe omettent les parenthèses. Si vous utilisez des parenthèses, la règle simple, mais parfois surprenante est la suivante : si ça ressemble à une fonction, alors c'est une fonction, ainsi la précédence n'a pas d'importance. Sinon, il s'agit d'un opérateur de liste ou d'un opérateur unaire, et la précédence devient importante. Soyez vigilants, car même si vous mettez un espace entre le mot-clef et sa parenthèse ouvrante, cela ne l'empêche pas d'être une fonction :

 
Sélectionnez
print 1+2*4;     # Affiche 9.
print(1+2) * 4;  # Affiche 3 !
print (1+2)*4;   # Affiche aussi 3 !
print +(1+2)*4;  # Affiche 12.
print ((1+2)*4); # Affiche 12.

Perl peut vous avertir de cette situation, si vous le lancez avec l'option -w. Par exemple, la deuxième et la troisième ligne ci-dessus donneront ce type de messages :

 
Sélectionnez
print () interpreted as function at -line 2.
Useless use of integer multiplication (*) in void context at -line 2.

Avec la simple définition de certaines fonctions, vous avez une latitude considérable dans la manière de passer des arguments. Par exemple, la façon la plus habituelle d'utiliser chmod est de passer les permissions du fichier (le mode) comme argument initial :

 
Sélectionnez
chmod 0644, @tableau;

mais la définition de chmod indique juste :

 
Sélectionnez
chmod LISTE

ainsi vous pouvez tout aussi bien écrire :

 
Sélectionnez
unshift @tableau, 0644;
chmod @tableau;

Si le premier argument de la liste n'est pas un mode valide, chmod échouera, mais c'est un problème sémantique à l'exécution sans rapport avec la syntaxe de l'appel. Si la sémantique réclame des arguments spéciaux à donner en premier, le texte décrira ces restrictions.

Au contraire des simples fonctions de LISTE, d'autres fonctions imposent des contraintes syntaxiques supplémentaires. Par exemple, push a un résumé de syntaxe comme ceci :

 
Sélectionnez
push TABLEAU, LISTE

Cela veut dire que push demande un tableau correct comme premier argument, mais ne tient pas compte des arguments suivants. C'est ce que signifie le LISTE à la fin. (Les LISTE viennent toujours à la fin, puisqu'elles englobent toutes les valeurs qui restent). Si le résumé de syntaxe contient des arguments avant la LISTE, ces arguments sont distingués syntaxiquement par le compilateur, et non seulement distingués sémantiquement par l'interpréteur lorsqu'on le lancera plus tard. De tels arguments ne sont jamais évalués dans un contexte de liste. Ils peuvent être évalués soit dans un contexte scalaire, soit ce sont des références spéciales comme le tableau dans push. (La description vous dira qui est qui.)

Pour les opérations qui sont directement basées sur les fonctions de la bibliothèque C, nous n'essayerons pas de dupliquer la documentation de votre système. Lorsque la description d'une fonction demande de voir fonction(2), cela signifie que vous devez vous référer à la version correspondante en C de cette fonction pour en savoir plus sur sa sémantique. Le nombre entre parenthèses indique la section du manuel de programmation système dans laquelle vous trouverez la page man, si vous avez installé les pages man. (Et dans laquelle vous ne trouverez rien, si vous n'avez rien installé.)

Ces pages de manuel peuvent documenter des comportements spécifiques de votre système, comme les mots de passe shadow, les listes de contrôle d'accès et ainsi de suite. De nombreuses fonctions Perl dérivent de la bibliothèque C sous Unix, mais sont émulées même sur les autres plates-formes. Par exemple, même si votre système d'exploitation ne connaît pas les appels système flock(2) et fork(2), Perl fait de son mieux pour les émuler avec les ressources natives de votre plate-forme.

Parfois, vous constaterez que, dans la documentation, la fonction C reçoit plus d'arguments que la fonction Perl correspondante. En général, les arguments supplémentaires sont déjà connus par Perl, comme la longueur d'un autre argument. Les autres différences viennent de la façon dont Perl et C spécifient les handles de fichiers, ainsi que les valeurs de succès et d'échec.

En général, les fonctions en Perl qui servent de sur-couches aux appels système du même nom (comme chown(2), fork(2), closedir(2), etc.) renvoient toutes une valeur vraie lorsqu'elles réussissent, sinon undef comme indiqué dans les descriptions qui suivent. Ceci est différent des interfaces C à ces opérations, lesquelles retournent toutes -1 en cas d'échec. Les exceptions à cette règle sont wait, waitpid et syscall. Les appels système positionnent aussi la variable spéciale $! ($OS_ERROR). Les autres fonctions ne le font pas, excepté accidentellement.

Pour les fonctions qui peuvent être utilisées aussi bien dans un contexte scalaire que dans un contexte de liste, un échec est généralement indiqué dans un contexte scalaire en retournant une valeur fausse (en général undef) et dans un contexte de liste en retournant une liste vide. La réussite de l'opération est généralement indiquée en renvoyant une valeur qui sera évaluée comme vraie (dans le contexte).

Retenez la règle suivante : il n'y a pas de règle qui relie le comportement d'une fonction dans un contexte de liste à son comportement dans un contexte scalaire, ou vice versa. Il peut s'agir de deux choses totalement différentes.

Chaque fonction connaît le contexte dans lequel elle a été appelée. La même fonction, qui renvoie une liste lorsqu'on l'appelle dans un contexte de liste, retournera, lorsqu'on l'appelle dans un contexte scalaire, la valeur qui lui semble la plus appropriée. Certaines fonctions renvoient la longueur de la liste qui aurait été retournée dans un contexte de liste. D'autres fonctions retournent « l'autre » valeur, lorsque quelque chose peut être manipulé, soit par un nombre, soit par son nom. D'autres encore renvoient un compteur des opérations qui ont réussi. En général, les fonctions de Perl font exactement ce que vous voulez faire, à moins que vous ne vouliez de la cohérence.

Une dernière Remarque : nous avons essayé d'être très cohérents dans notre emploi des termes octets et caractères. Historiquement, ces termes ont été confondus l'un avec l'autre (et avec eux-mêmes). Mais lorsque nous disons octet, nous désignons toujours un octet de 8 bits. Lorsque nous disons caractère, nous voulons dire un caractère dans son abstraction, généralement un caractère Unicode, lequel peut être représenté dans vos chaînes par un ou plusieurs octets.

Mais notez que nous avons dit « généralement ». Perl confond à dessein les octets avec les caractères dans le contexte d'une déclaration use bytes, ainsi à chaque fois que nous parlons de caractère, vous devez comprendre un octet dans un contexte use bytes, sinon un caractère Unicode. En d'autres termes, use bytes reprend la définition d'un caractère telle qu'on la concevait dans les précédentes versions de Perl. Par exemple, si nous disons qu'un reverse scalaire, inverse une chaîne caractère par caractère, ne nous demandez pas si cela veut vraiment dire caractères ou alors octets, car la réponse est : « Oui».

29-1. Fonctions Perl par catégorie

Voici les fonctions de Perl et les mots-clefs assimilés, classés par catégorie. Certaines fonctions apparaissent sous plusieurs en-têtes.

Manipulation de scalaires

  • chomp, chop, chr, crypt, hex, index, lc, lcfirst, length, oct, ord, pack, q//, qq//, reverse, rindex, sprintf, substr, tr///, uc, ucfirst, y///

Expressions rationnelles et recherche de motifs

  • m//, pos, qr//, quotemeta, s///, split, study

Fonctions numériques

  • abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt, srand

Traitement des tableaux

  • pop, push, shift, splice, unshift

Traitement des listes

  • grep, join, map, qw//, reverse, sort, unpack

Traitement des hachages

  • delete, each, exists, keys, values

Entrées et sorties

  • binmode, close, closedir, dbmclose, dbmopen, die, eof, fileno, flock, format, getc, print, printf, read, readdir, readpipe, rewinddir, seek, seekdir, select (descripteurs de fichiers prêts), syscall, sysread, sysseek, syswrite, tell, telldir, truncate, warn, write

Données et enregistrements de longueur fixe

  • pack, read, syscall, sysread, sysseek, syswrite, unpack, vec

Handles de fichiers, fichiers et répertoires

  • chdir, chmod, chown, chroot, fcntl, glob, ioctl, link, lstat, mkdir, open, opendir, readlink, rename, rmdir, select (descripteurs de fichiers prêts), select (handle du fichier de sortie), stat, symlink, sysopen, umask, unlink, utime

Contrôle de flux des programmes

Potée

Divers

Processus et groupes de processus

  • alarm, exec, fork, getpgrp, getppid, getpriority, kill, pipe,qx//, setpgrp, setpriority, sleep, system, times, wait, waitpid

Modules de bibliothèques

Classes et objets

  • bless, dbmclose, dbmopen, package, ref, tie, tied, untie, use

Accès aux sockets de bas niveau

  • accept, bind, connect, getpeername, getsockname, getsockopt, listen, recv, send, setsockopt, shutdown, socket, socketpair

Communications interprocessus System V

  • msgctl, msgget, msgrcv, msgsnd, semctl, semget, semop, shmctl, shmget, shmread, shmwrite

Recherches d'informations sur les groupes et les utilisateurs

  • endgrent, endhostent, endnetent, endpwent, getgrent, getgrgid, getgrnam, getlogin, getpwent, getpwnam, getpwuid, setgrent, setpwent

Recherches d'informations réseaux

  • endprotoent, endservent, gethostbyaddr, gethostbyname, gethostent, getnetbyaddr, getnetbyname, getnetent, getprotobyname, getprotobynumber, getprotoent, getservbyname, getservbyport, getservent, sethostent, setnetent, setprotoent, setservent

Date et heure

  • gmtime, localtime, time, times

29-2. Fonctions Perl par ordre alphabétique

La plupart des fonctions suivantes sont annotées avec, euh, des annotations. Voici leur signification :

Image non disponible Utilise $_ ($ARG) comme variable par défaut.

Image non disponible Modifie $! ($OS_ERROR) pour les erreurs dans les appels système.

Image non disponible Lève des exceptions ; utilisez eval pour intercepter $@ ($EVAL_ERROR).

Image non disponible Modifie $? ($CHILD_ERROR) lorsque le processus fils se termine.

Image non disponible Marque la donnée retournée.

Image non disponible Marque la donnée retournée dans certains systèmes, localement, ou configurée manuellement.

Image non disponible Lève une exception si un argument d'un type inapproprié est donné.

Image non disponible Lève une exception si on modifie une cible en lecture seule.

Image non disponible Lève une exception si on l'alimente avec une donnée marquée.

Image non disponible Lève une exception s'il n'existe pas d'implémentation sur la plate-forme courante.

Les fonctions qui retournent une donnée marquée lorsqu'elles sont alimentées avec une donnée marquée ne sont elles-mêmes pas marquées, puisque c'est le cas de la plupart des fonctions. En particulier, si vous utilisez n'importe quelle fonction avec %ENV ou @ARGV, vous obtiendrez une donnée marquée.

Les fonctions annotées avec Image non disponible lèvent une exception lorsqu'elles attendent, mais ne reçoivent pas, un argument d'un type précis (comme des handles de fichiers pour les opérations d'entrée/sortie, des références pour bless, etc.).

Les fonctions annotées avec Image non disponible ont parfois besoin de modifier leurs arguments. Si elles ne peuvent pas modifier l'argument, car il est marqué en lecture seule, elles lèvent une exception. Des exemples de variables en lecture seule sont les variables spéciales contenant une donnée capturée durant une recherche de motif et les variables qui sont en fait des alias de constantes.

Les fonctions annotées avec Image non disponible peuvent ne pas être implémentées sur toutes les plates-formes. Bien que la plupart d'entre elles soient nommées d'après les fonctions de la bibliothèque C sous Unix, ne croyez pas que vous ne pouvez en appeler aucune, seulement parce que vous n'êtes pas sous Unix. Beaucoup sont émulées, même celles que vous n'espériez jamais voir — comme fork sur les systèmes Win32, qui est en place depuis la version 5.6 de Perl. Pour plus d'informations sur la portabilité et le comportement de fonctions spécifiques à un système, voir la page de man perlport, plus quelques documentations spécifiques à la plate-forme fournie par votre portage de Perl.

Les fonctions qui lèvent d'autres exceptions diverses et variées sont annotées avec Image non disponible, y compris les fonctions mathématiques qui émettent des erreurs d'intervalle, comme sqrt(-1).

abs Image non disponible

 
Sélectionnez
abs VALEUR
abs

Cette fonction renvoie la valeur absolue de son argument.

 
Sélectionnez
$diff = abs($premier -$second);

Remarque : ici et dans les exemples suivants, un bon style (et le pragma use strict) exigerait que vous ajoutiez un modificateur my pour déclarer une nouvelle variable de portée lexicale, comme ceci :

 
Sélectionnez
my $diff = abs($premier -$second);

Toutefois, nous avons omis my de la plupart de nos exemples pour plus de clarté. Vous n'avez qu'à supposer qu'une telle variable a été déclarée plus tôt, si cela vous démange.

accept Image non disponible Image non disponible Image non disponible

 
Sélectionnez
accept SOCKET, SOCKET_PROTO

Cette fonction est utilisée par les processus serveurs qui désirent se mettre en attente de connexion de clients sur une socket. SOCKET_PROTO doit être un handle de fichier déjà ouvert via l'opérateur socket et attaché à l'une des adresses réseau du serveur ou à INADDR_ANY. L'exécution est suspendue jusqu'à ce qu'une connexion soit établie, un handle de fichier SOCKET étant alors ouvert et attaché à la nouvelle connexion. Le handle original SOCKET_PROTO reste inchangé ; son seul but est d'être clôné dans une véritable socket. La fonction renvoie l'adresse de la connexion si l'appel réussit, une valeur fausse sinon. Par exemple :

 
Sélectionnez
unless ($interlocuteur = accept(SOCK, SOCK_PROTO)) {
    die "Ne peut accepter la connexion : $!\n";
}

Sur les systèmes qui l'acceptent, le flag close-on-exec sera positionné pour le nouveau descripteur de fichier ouvert, comme le veut la valeur de $^F ($SYSTEM_FD_MAX).

Voir accept(2). Voir aussi l'exemple dans la section Sockets au chapitre 16, Communication interprocessus.

alarm Image non disponible Image non disponible

 
Sélectionnez
alarm EXPR
alarm

Cette fonction envoie un signal SIGALRM au processus courant après EXPR secondes.

Un seul minuteur (timer) peut être actif à un moment donné. Chaque appel désactive le précédent minuteur et un argument EXPR valant 0 peut être fourni pour annuler le minuteur précédent sans en lancer un de nouveau.

 
Sélectionnez
print "Répondez en une minute ou allez en enfer : ";
alarm(60);                # tue le programme dans une minute
$reponse = <STDIN>;
$temps_restant = alarm(0) # efface l'alarme
print "Il vous reste $temps_restant secondes\n";

Une erreur courante est de mélanger les appels à alarm et sleep, car nombre de systèmes utilisent le mécanisme de l'appel système à alarm(2) pour implémenter sleep(3). Sur des machines plus anciennes, le temps écoulé peut être jusqu'à une seconde inférieur à celui que vous avez spécifié, selon la manière dont sont comptées les secondes. De plus, un système surchargé peut ne pas être prêt à lancer votre processus immédiatement. Voir le chapitre 16 pour plus d'informations sur l'interception de signaux.

Pour des alarmes d'une granularité plus fine que la seconde, vous pouvez utiliser la fonction syscall pour accéder à setitimer(2) si votre système le supporte. Le module CPAN, Timer::HiRes offre aussi des fonctions dans cet objectif.

atan2

 
Sélectionnez
atan2 Y, X

Cette fonction renvoie la valeur principale de l'arctangente de Y/X dans l'intervalle de -π à π. Un moyen rapide d'obtenir une valeur approchée de ! est d'écrire :

 
Sélectionnez
$pi = atan2(1, 1) * 4;

Pour la tangente, vous pouvez utiliser la fonction tan provenant soit du module Math::Trig, soit du module POSIX, ou employer la relation bien connue :

 
Sélectionnez
sub tan { sin($_[0] / cos($_[0]) }

bind Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
bind SOCKET, NOM

Cette fonction attache une adresse (un nom) à une socket déjà ouverte, spécifiée par le handle de fichier SOCKET. La fonction renvoie vrai si elle a réussi, sinon faux. NOM doit être une adresse empaquetée de la socket avec le type approprié.

 
Sélectionnez
use Socket;
$numero_port = 80;  # prétend que nous voulons être un serveur web
$adresse_socket = sockaddr_in($numero_port, INADDR_ANY);
bind SOCK, $adresse_socket
or die "Impossible d'attacher $numero_port : $!\n";

Voir bind(2). Voir aussi les exemples de la section Sockets au chapitre 16.

binmode Image non disponible

 
Sélectionnez
binmode HANDLE_FICHIER, DISCIPLINES
binmode HANDLE_FICHIER

Cette fonction s'arrange pour que le HANDLE_FICHIER ait la sémantique spécifiée par l'argument DISCIPLINES. Si l'on omet DISCIPLINES, des sémantiques binaires (ou « raw ») sont appliquées au handle de fichier. Si HANDLE_FICHIER est une expression, la valeur est prise de manière appropriée, comme le nom du handle de fichier ou comme une référence à un handle de fichier.

La fonction binmode doit être appelée après l'open mais avant qu'une quelconque opération d'entrée/sortie sur le handle de fichier n'ait été effectuée. Le seul moyen de réinitialiser le mode d'un handle de fichier est de rouvrir le fichier, puisque les diverses disciplines ont pu conserver divers bits et segments de données dans diverses mémoires tampons. Cette restriction est susceptible d'être levée à l'avenir.

Autrefois, binmode était principalement utilisé sur les systèmes d'exploitation dont les bibliothèques d'exécution distinguaient les fichiers textes des fichiers binaires. Sur ces systèmes, l'objectif de binmode était de désactiver la sémantique de texte par défaut. De toute façon, depuis l'avènement d'Unicode, tous les programmes sur tous les systèmes doivent connaître la distinction, même sur les systèmes Unix ou Mac. De nos jours, il n'existe qu'un type de fichiers binaire (du moins pour Perl), mais une multitude de types de fichiers texte. Ainsi, Perl ne connaît qu'un seul format interne pour les textes Unicode, UTF-8. Puisqu'il existe une variété de fichiers texte, ceux-ci doivent souvent être convertis en entrée vers UTF-8 et en sortie vers le jeu de caractères d'origine ou vers une autre représentation d'Unicode. Vous pouvez utiliser les disciplines pour indiquer à Perl comment réaliser exactement (ou inexactement) ces conversions.(199)

Par exemple, une discipline de ":text" dira à Perl de traiter les textes de façon générique sans préciser quel type de texte traiter. Mais des disciplines comme ":utf8" ou ":latin1" disent à Perl quel format de texte lire et écrire. D'un autre côté, la discipline ":raw" prévient Perl de garder ses sales mains en dehors des données. Pour en savoir plus sur le fonctionnement (éventuellement futur) des disciplines, voir la fonction open. La suite de cette discussion décrit ce que binmode fait sans l'argument DISCIPLINES, c'est-à-dire la signification historique de binmode, qui est équivalente à :

 
Sélectionnez
binmode HANDLE_FICHIER, ":raw";

Sauf indication contraire, Perl suppose que votre fichier fraîchement ouvert doit être lu ou écrit en mode texte. Le mode texte signifie que \n (newline) est votre caractère fin de ligne interne. Tous les systèmes utilisent \n comme leur caractère de fin de ligne interne, mais ce qu'il représente réellement varie d'un système à l'autre, d'un périphérique à un autre et même d'un fichier à un autre, selon la façon dont vous accédez au fichier. Sur de tels systèmes (comprenant MS-DOS et VMS), ce que votre programme voit comme un \n peut ne pas être ce qui est stocké physiquement sur le disque. Le système d'exploitation peut, par exemple, stocker des fichiers textes avec les séquences \cM\cJ qui sont converties en entrée pour apparaître comme \n dans votre programme et inversement convertir \n depuis votre programme vers \cM\cJ en sortie dans un fichier. La fonction binmode désactive cette conversion automatique sur de tels systèmes.

En l'absence d'un argument DISCIPLINES, binmode n'a aucun effet sous Unix ou MAC OS, tous deux utilisant \n pour terminer chaque fin de ligne et représentant ceci avec un seul caractère. (Il peut s'agir toutefois d'un autre caractère : Unix utilise \cJ et les anciens Macs \cM. Mais cela ne porte pas à conséquence.)

Les exemples suivants montrent comment un script Perl doit lire une image GIF depuis un fichier et l'afficher sur la sortie standard. Sur les systèmes qui autrement altéreraient les données littérales en quelque chose d'autre que leur exacte représentation physique, vous devez préparer les deux handles de fichiers. Alors que vous pourriez directement utiliser une discipline ":raw" pour ouvrir le fichier GIF, vous ne pouvez pas si facilement faire de même avec les handles de fichiers déjà ouverts, tels que STDOUT :

 
Sélectionnez
binmode STDOUT;
open(GIF, "vim-power.gif") or die "Impossible d'ouvrir vim-power.gif : $!\n";
binmode GIF;
while (read(GIF, $buf, 1024)) {
    print STDOUT $buf;
}

bless Image non disponible

 
Sélectionnez
bless REF, NOM_DE_CLASSE
bless REF

Cette fonction indique à l'objet sur lequel pointe REF qu'il est maintenant un objet du paquetage NOM_DE_CLASSE — ou du paquetage courant si aucun NOM_DE_CLASSE n'est spécifié. Si REF n'est pas une référence valide, une exception est levée. Pour des raisons pratiques, bless retourne la référence, puisque c'est souvent la dernière fonction d'un constructeur. Par exemple :

 
Sélectionnez
dromadaire = Animal->nouveau(TYPE => "Chameau", NOM => "amelia");

# puis dans Amimal.pm :
sub nouveau {
    my $classe = shift;
    my %attrs = @_;
    my $obj = { %attrs };
    return bless($obj, $classe);
}

Vous devez généralement consacrer les objets avec bless dans des NOMS_DE_CLASSE en majuscules et minuscules mélangées. Les espaces de noms tout entiers en minuscules sont réservés pour des besoins internes, comme les pragmas (directives de compilation) de Perl. Les types prédéfinis (tels que « SCALAR », « ARRAY », « HASH », etc., pour ne pas mentionner la classe de base de toutes les classes, « UNIVERSAL ») sont tous en majuscules, alors peut-être vaut-il mieux que vous évitiez des noms de paquetages écrits ainsi.

Assurez-vous que NOM_DE_CLASSE ne soit pas à une valeur fausse, la consécration dans des paquetages faux n'est pas supportée et peut conduire à des résultats imprévisibles.

Ce n'est pas un bogue qu'il n'y ait pas d'opérateur curse correspondant. (Mais il existe un opérateur sin, jeu de mots intraduisible, l'opérateur sin s'occupant de la fonction sinus et non d'un quelconque blasphème.) Voir aussi le chapitre 12, Objet, pour en savoir plus sur la bénédiction (et les consécrations) des objets.

caller

 
Sélectionnez
caller EXPR
caller

Cette fonction renvoie des informations concernant la pile d'appels en cours de sous-programmes et assimilés. Sans argument, elle renvoie le nom du paquetage, le nom du fichier et le numéro de ligne d'où la routine en cours d'exécution a été appelée :

 
Sélectionnez
($paquetage, $fichier, $ligne) = caller;

Voici un exemple d'une fonction extrêmement fastidieuse, qui utilise les tokens spéciaux __PACKAGE__ et __FILE__ décrit au chapitre 2, Composants de Perl :

 
Sélectionnez
sub attention {
    my ($paquetage, $fichier) = caller;
    unless ($paquetage eq __PACKAGE__ && $file eq __FILE__) {
        die "Vous n'êtes pas supposé m'appeller, $paquetage !\n";
    }
    print "Appelez-moi en toute tranquillité\n";
}
sub appel_tranquille {
    attention();
}

Appelée avec un argument, caller interprète EXPR comme étant le nombre de groupes d'éléments dans la pile (stack frames) à remonter avant la routine courante. Par exemple, un argument de 0 signifie l'élément courant dans la pile ; 1, la routine appelante ; 2, la routine appelante de la routine appelante ; et ainsi de suite. La fonction renvoie également des informations supplémentaires, comme le montre l'exemple suivant :

 
Sélectionnez
$i= 0;
while (($paquetage, $fichier, $ligne, $routine,
        $args_presents, $tableau_demande, $texte_eval, $est_requis,
        $indications, $masque_de_bits) = caller($i++))
{
    ...
}

Si l'élément est un appel de sous-programme, $args_presents est vrai s'il possède son propre tableau @_ (et non un qui soit emprunté à la routine qui l'a appelé). Sinon, $routine peut valoir « (eval) » si l'élément n'est pas un appel de sous-programme, mais un eval. Si c'est le cas, les informations supplémentaires $texte_eval et $est_requis sont positionnées : $est_requis est vrai si l'élément est créé par une instruction require ou un use, et $texte_eval contient le texte de l'instruction eval EXPR. Plus particulièrement, pour une instruction eval BLOCK, $fichier vaut « (eval) », mais $texte_eval est indéfini. (Remarquez également que chaque instruction use crée un élément require dans un élément eval EXPR.) $indications et $masque_de_bits sont des valeurs internes ; vous êtes priés de les ignorer à moins que vous ne soyez membre de la thaumatocratie.

Dans un esprit de magie encore plus poussée, caller positionne également le tableau @DB::args avec les arguments passés à l'élément donné de la pile — mais seulement lorsqu'on l'appelle depuis le paquetage DB. Voir le chapitre 20, Le débogueur Perl.

chdir Image non disponible Image non disponible

 
Sélectionnez
chdir EXPR
chdir

Cette fonction change le répertoire de travail du processus courant en EXPR, si cela est possible. Si EXPR est omise, on utilise le répertoire de base de l'utilisateur. La fonction renvoie vraie si elle réussit, sinon faux.

 
Sélectionnez
chdir "$prefixe/lib" or die "Impossible de faire un cd dans $prefixe/lib\n";

Voir aussi le module Cwd, décrit au chapitre 32, Modules standard, qui vous permet de garder automatiquement une trace de votre répertoire courant.

chmod Image non disponible Image non disponible

 
Sélectionnez
chmod LISTE

Cette fonction modifie les permissions d'une liste de fichiers. Le premier élément de la liste doit être le mode numérique, comme dans l'appel système chmod(2). La fonction renvoie le nombre de fichiers modifiés avec succès. Par exemple :

 
Sélectionnez
$compt = chmod 0755, 'fichier1', 'fichier2';

affectera 0, 1 ou 2 à $compt, selon le nombre de fichiers modifiés. L'opération est jugée réussie par l'absence d'erreur et non par un véritable changement, car un fichier peut avoir le même mode qu'avant l'opération. Une erreur signifie vraisemblablement que vous manquez de privilèges suffisants pour changer le mode du fichier, car vous n'êtes ni son propriétaire ni le super-utilisateur. Vérifiez $! pour découvrir la cause réelle de l'échec.

Voici une utilisation plus typique :

 
Sélectionnez
chmod(0755, @executables) == @executables 
  or die "Modification impossible de certains éléments de @executables : $!";

Si vous devez connaître quels fichiers n'ont pas pu être changés, écrivez quelque chose comme ceci :

 
Sélectionnez
@immuables = grep {not chmod 0755, $_} 'fichier1', 'fichier2', 'fichier3';
die "$0 : impossible d'exécuter chmod @immuables\n" if @immuables;

Cet idiome utilise la fonction grep pour ne sélectionner que les éléments de la liste pour lesquels la fonction chmod a échoué.

Lorsque des données non littérales sont utilisées pour le mode, vous pouvez avoir besoin de convertir une chaîne octale en un nombre décimal en utilisant la fonction oct. Ceci, car Perl ne devine pas automatiquement qu'une chaîne contient un nombre octal seulement parce qu'elle commence par un « 0 ».

 
Sélectionnez
$MODE_DEFAUT = 0644; # On ne peut pas utiliser de guillemets ici !
PROMPT: {
    print "Nouveau mode ? ";
    $chaine_mode = <STDIN>;
        exit unless defined $chaine_mode; # test de fin de fichier
    if ($chaine_mode =~ /^\s*$/ {         # test de ligne à blanc
        $mode = $MODE_DEFAUT;
    }
    elsif ($chaine_mode !~ /^\d+$/) {
        print "Demande un mode numérique, $chaine_mode invalide\n";
        redo PROMPT;
    }
    else {
        $mode = oct($chaine_mode);        # convertit "755" en 0755
    }
    chmod $mode, @fichiers;
}

Cette fonction marche avec des modes numériques comme dans l'appel système Unix chmod(2). Si vous voulez une interface symbolique comme celle fournie par la commande chmod(1), voir le module File::chmod de CPAN.

Vous pouvez aussi importer les constantes symboliques S_I* du module Fcntl :

 
Sélectionnez
use Fcntl ':mode';
chmod S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, @executables;

Certains considèrent que ceci est plus lisible qu'avec 0755. Maintenant, c'est à vous de voir.

chomp Image non disponible Image non disponible

 
Sélectionnez
chomp VARIABLE
chomp LISTE
chomp

Cette fonction supprime (normalement) un saut de ligne à la fin d'une chaîne contenue dans une variable. Il s'agit d'une fonction légèrement plus sûre que chop (décrite ci-dessous) en ce qu'elle n'a pas d'effet sur une chaîne ne se terminant pas par un saut de ligne. Plus précisément, elle supprime la fin d'une chaîne correspondant à la valeur courante de $/, et non n'importe quel caractère de fin.

À l'inverse de chop, chomp renvoie le nombre de caractères supprimés. Si $/ vaut "" (en mode paragraphe), chomp enlève tous les caractères de fin de ligne à la fin de la chaîne sélectionnée (ou des chaînes si l'on « chompe » une LISTE). Vous ne pouvez pas « chomp er » un littéral, seulement une variable.

Par exemple :

 
Sélectionnez
while (<PASSWD>) {
    chomp; # évite d'avoir \n dans le dernier champ
    @tableau = split /:/;
    ...
}

Avec la version 5.6, la signification de chomp change légèrement en ce que les disciplines en entrée peuvent prendre le dessus sur la valeur de la variable $/ et affecter la manière dont les chaînes doivent être « chompées ». Ceci a l'avantage qu'une discipline en entrée peut reconnaître plus d'une variété de délimiteurs de ligne (comme un paragraphe Unicode et les séparateurs de ligne), mais « chomp e » encore en toute sécurité tout ce qui termine la ligne courante.

chop Image non disponible Image non disponible

 
Sélectionnez
chop VARIABLE
chop LISTE
chop

Cette fonction coupe le dernier caractère d'une chaîne et renvoie le caractère coupé. L'opérateur chop est utilisé en premier lieu pour couper le caractère fin de ligne à la fin d'un enregistrement en entrée, mais est plus efficace qu'une substitution. Si c'est tout ce que vous en faites, alors il est plus sûr d'utiliser chomp, puisque chop tronque toujours la chaîne d'un caractère quel qu'il soit, alors que chomp est plus sélectif.

Vous ne pouvez pas « choper » un littéral, seulement une variable.

Si vous « chopez » une LISTE de variables, chacune des chaînes de la liste est coupée :

 
Sélectionnez
@lignes = 'cat mon_fichier';
chop @lignes;

Vous pouvez « choper » tout ce qui est une lvalue, y compris une affectation :

 
Sélectionnez
chop($rep_courant = 'pwd');
chop($reponse = <STDIN>);

Ce qui est différent de :

 
Sélectionnez
$reponse = chop($tmp = <STDIN>); # MAUVAIS

qui met un caractère fin de ligne dans $reponse puisque chop renvoie le caractère éliminé et non la chaîne résultante (qui se trouve dans $tmp). Une manière d'obtenir le résultat voulu est d'utiliser substr :

 
Sélectionnez
$reponse = substr <STDIN>, 0, -1;

Mais on l'écrit plus fréquemment :

 
Sélectionnez
chop($reponse = <STDIN>);

La plupart du temps, on peut exprimer chop en termes de substr :

 
Sélectionnez
$dernier_caractere = chop($var);
$dernier_caractere = substr($var, -1, 1, ""); # la même chose

Une fois que vous aurez compris cette équivalence, vous pourrez l'utiliser pour faire des coupes plus évoluées. Pour couper plus d'un caractère, utilisez substr comme une lvalue, en assignant une chaîne vide. Ce qui suit enlève les cinq derniers caractères de $caravane :

 
Sélectionnez
substr($caravane, -5) = "";

Le paramètre négatif fait partir substr de la fin de la chaîne au lieu du début. Si vous voulez récupérer les caractères ainsi enlevés, vous pouvez employer la forme à quatre arguments de substr, créant ainsi quelque chose comme un quintuple « chop » :

 
Sélectionnez
$queue = substr($caravane, -5, 5, "");

chownImage non disponible Image non disponible Image non disponible

 
Sélectionnez
chown LISTE

Cette fonction change le propriétaire et le groupe d'une liste de fichiers. Les deux premiers éléments de la liste doivent être les UID et GID numériques, dans cet ordre. Une valeur de -1, dans l'une ou l'autre position, est interprétée par la plupart des systèmes en conservant la valeur inchangée. La fonction renvoie le nombre de fichiers modifiés avec succès. Par exemple :

 
Sélectionnez
($compt = chown($uidnum, $gidnum, 'fichier1', 'fichier2')) == 2
    or die "chown impossible pour fichier1 ou fichier2 : $!";

mettra $compt à 0, 1 ou 2, selon le nombre de fichiers modifiés (dans le sens où l'opération s'est déroulée avec succès, et non selon que le propriétaire est différent après coup). Voici une utilisation plus typique :

 
Sélectionnez
chown($uidnum, $gidnum, @fichiers) == @fichiers
    or die "Modification impossible de @fichiers avec chown : $!";

Voilà un sous-programme qui accepte un nom d'utilisateur, vérifie les UID et GID pour vous, puis effectue le chown :

 
Sélectionnez
sub chown_avec_le_nom {
    my ($utilisateur, @fichiers) = @_;
    chown((getpwnam($utilisateur))[2,3], @fichiers) == @fichiers
        or die "chown impossible pour @fichiers : $!";
}

chown_avec_le_nom("larry", glob("*.c"));

Cependant, il se peut que vous ne vouliez pas modifier le groupe ainsi que le fait la fonction précédente, car le fichier /etc/passwd associe à chaque utilisateur, un groupe unique même si cet utilisateur peut être membre de plusieurs groupes secondaires dans /etc/groups. Dans ce cas, vous pouvez passer -1 pour le GID, ce qui laisse inchangé le groupe du fichier. Si vous passez -1 comme UID et un GID valide, vous pouvez affecter le groupe sans changer l'utilisateur.

Sur la plupart des systèmes, vous n'avez la permission de changer le propriétaire du fichier que si vous êtes le super-utilisateur, bien que vous puissiez changer le groupe en n'importe lequel de vos groupes secondaires. Sur des systèmes peu sûrs, ces restrictions peuvent être assouplies, mais cette supposition n'est pas généralisable. Sur les systèmes POSIX, vous pouvez détecter quelle règle s'applique ainsi :

 
Sélectionnez
use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
# essayez seulement si vous êtes le super-utilisateur
# ou sur un système permissif
if ($> == 0 || !sysconf(_PC_CHOWN_RESTRICTED)) {
    chown($uidnum, -1, $fichier)
        or die "chown de $fichier à $uidnum impossible : $!";

chr Image non disponible

 
Sélectionnez
chr NOMBRE
chr

Cette fonction renvoie le caractère représenté par ce NOMBRE dans le jeu de caractères. Par exemple, chr(65) vaut « A » en ASCII comme en Unicode, et chr(0x263a) est un smiley Unicode. Pour obtenir l'inverse de chr, utilisez ord.

Si vous préférez spécifier votre caractère par son nom plutôt que par un nombre (par exemple, "\N{WHITE SMILING FACE}" pour un smiley Unicode), voir charname au chapitre 31, Modules de pragmas.

chroot Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
chroot FICHIER
chroot

En cas de succès, FICHIER devient le nouveau répertoire racine pour le processus courant, le point de départ des noms de chemin commençant par « / ». Ce répertoire est hérité par appels à exec et par tous les sous-processus forkés après l'appel à chroot. Il n'y a aucun moyen de revenir à l'état précédent un chroot. Pour des raisons de sécurité, seul le super-utilisateur peut utiliser cette fonction. Voici un morceau de code ressemblant approximativement à ce que font de nombreux serveurs FTP :

 
Sélectionnez
chroot((getpwnam('ftp'))[7]
    or die "Ftp anonyme impossible : $!\n";

Il est improbable que cette fonction marche sur des systèmes non Unix. Voir chroot(2).

close Image non disponible Image non disponibleImage non disponible

 
Sélectionnez
close HANDLE
close

Cette fonction ferme le fichier, la socket ou le pipe associé au HANDLE. (Elle ferme le handle de fichier actuellement sélectionné si l'argument est omis.) Elle renvoie vrai si la fermeture se déroule avec succès, sinon faux. Vous n'avez pas besoin de fermer HANDLE si vous le rouvrez immédiatement, puisque le open suivant le ferme automatiquement pour vous. (Voir open.) Cependant, un close explicite sur un fichier en entrée remet à zéro le compteur de lignes ($.), ce qui n'est pas le cas de la fermeture implicite effectuée par open.

HANDLE peut être une expression dont la valeur peut être employée en tant que handle de fichier indirect (soit le non réel du handle de fichier, soit une référence à tout ce qui peut être interprété comme un objet handle de fichier.)

Si le handle de fichier vient d'une ouverture de pipe, close renverra faux si un appel système sous-jacent échoue ou si le programme à l'autre extrémité du pipe se termine avec un statut non nul. Dans ce dernier cas, le close force la variable $! ($OS_ERROR)à zéro. Donc, si un close sur un pipe renvoie un statut non nul, vérifiez $! pour déterminer si le problème vient du pipe lui-même (valeur non nulle) ou du programme à l'autre bout du pipe (valeur nulle). Dans tous les cas, $? ($CHILD_ERROR) contient la valeur de statut d'attente (N.d.T. : wait status ; voir son interprétation à la fonction system) de la commande associée à l'autre extrémité du pipe. Par exemple :

 
Sélectionnez
open(SORTIE, '| sort -rn | lpr -p') # pipe pour sort et lpr
    or die "Impossible de démarrer le pipe sortlpr : $!";
print SORTIE @lignes;               # imprime des choses sur la sortie
close SORTIE                        # attend que le sort finisse
    or warn $! ? "Erreur système lors de la fermeture du pipe sortlpr : $!"
               : "Statut d'attente du pipe sortlpr $?";

Un handle de fichier produit, en dupliquant (2) un pipe, est traité comme un handle de fichier ordinaire, ainsi close n'attendra pas le fils pour ce handle de fichier. Vous devez attendre le fils en fermant le handle de fichier d'origine. Par exemple :

 
Sélectionnez
open(NESTSTAT, "netstat -rn |")
    or die "Impossible de lancer netstat : $!";
open (STDIN, "<&NETSTAT")
    or die "Impossible de dupliquer vers stdin : $!";

Si vous fermez le STDIN ci-dessus, il n'y aura pas d'attente ; par contre, il y en aura si vous fermez NETSTAT.

Si vous vous débrouillez d'une manière ou d'une autre pour récolter vous-même un pipe fils qui s'est terminé, le close échouera. Ceci peut arriver si vous avez votre propre gestionnaire pour $SIG{CHLD} qui se déclenche lorsque le pipe fils se termine, ou si vous appelez intentionnellement waitpid avec l'identifiant de processus renvoyé par l'appel de open.

closedir Image non disponible Image non disponible Image non disponible

 
Sélectionnez
closedir HANDLE_REP

Cette fonction ferme un répertoire ouvert par opendir et renvoie la réussite de l'opération. Voir les exemples de readdir. HANDLE_REP peut être une expression dont la valeur peut être employée en tant que handle de répertoire indirect, généralement le non réel du handle du répertoire.

connect Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
connect SOCKET, NOM

Cette fonction démarre une connexion avec un autre processus qui attend par un accept. La fonction renvoie vrai si elle réussit, faux sinon. NOM doit être une adresse réseau binaire du type correspondant à celui de la socket. Par exemple, en supposant que SOCK soit une socket créée préalablement :

 
Sélectionnez
use Socket;

my ($distant, $port) = ("www.perl.com", 80);
my $adr_dest = sockaddr_in($port, inet_aton($distant));
connect SOCK, $adr_dest
    or die "Connexion impossible vers $distant sur le port $port : $!";

Pour déconnecter une socket, utilisez soit close, soit shutdown. Voir aussi les exemples de la section Sockets au chapitre 16. Voir connect(2).

cos Image non disponible

 
Sélectionnez
cos EXPR
cos

Cette fonction renvoie le cosinus de EXPR (exprimée en radians). Par exemple, le script suivant affiche une table des cosinus d'angles mesurés en degrés :

 
Sélectionnez
# Voici la manière de ne pas se fatiguer pour convertir de degrés en radians

$pi = atan2(1,1) * 4;
$pi_apres_180 = $pi/180;

# Affiche la table
for ($deg = 0; $deg <= 90; $deg++) {
    printf "%3d %7.5f\n", $deg, cos($deg * $pi_apres_180);
}

Pour l'opération cosinus inverse, vous pouvez utilisez la fonction acos() des modules Math::Trig ou POSIX, ou encore utiliser cette relation :

 
Sélectionnez
sub acos { atan2( sqrt(1 -$_[0] * $_[0]), $_[0] ) }

crypt Image non disponible

 
Sélectionnez
crypt TEXTE_EN_CLAIR, PERTURBATION

Cette fonction calcule le hachage non bijectif d'une chaîne exactement comme le fait crypt(3). Ceci s'avère très utile pur vérifier que le fichier de mots de passe n'en contient pas qui soient trop faibles(200), bien que ce que vous vouliez réellement faire est d'empêcher les gens de commencer à en ajouter de mauvais.

crypt se veut une fonction non bijective, un peu comme casser des œufs pour faire une omelette. Il n'existe aucun moyen (connu) de décrypter un mot de passe chiffré, à moins d'essayer de deviner toutes les combinaisons de manière exhaustive.

Lorsque vous vérifiez une chaîne cryptée existante, vous devez utiliser le texte chiffré en tant que PERTURBATION (comme crypt($texte_en_clair, $crypte) eq $crypte). Ceci permet à votre code de fonctionner avec le crypt standard ainsi qu'avec d'autres implémentations plus exotiques.

Lorsque vous choisissez une nouvelle PERTURBATION, vous avez au moins besoin de créer une chaîne de deux caractères aléatoires appartenant à l'ensemble [./0-9A-Za-z] (comme join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]). Les anciennes implémentations de crypt avaient seulement besoin des deux premiers caractères de PERTURBATION, mais le code qui donnait seulement les deux premiers caractères est maintenant considéré comme non portable. Voir votre page de manuel locale de crypt(3) pour des détails intéressants.

Voici un exemple qui s'assure que quiconque lançant ce programme connaît son propre mot de passe :

 
Sélectionnez
$mot_de_passe = (getpwuid ($<))[1] # Suppose que l'on soit sur Unix.

system "stty -echo";               # ou regarder Term::Readkey dans CPAN
print "Mot de passe : ";
chomp($mot = <STDIN>);
print "\n";
system "stty echo";

if (crypt($mot, $mot_de_passe) ne $mot_de_passe) {
    print "Désolé\n";
} else {
    print "ok\n";
}

Il est bien sûr déconseillé de donner votre mot de passe à quiconque le demande, car c'est imprudent.

Les mots de passe cachés sont légèrement plus sûrs que les fichiers de mots de passe traditionnels et vous devez être le super-utilisateur pour y accéder. Comme peu de programmes doivent tourner avec des privilèges si puissants, il se peut que le programme maintienne son propre système d'authentification indépendant en stockant les chaînes crypt ées dans un fichier autre que /etc/passwd ou /etc/shadow.

La fonction crypt n'est pas adaptée au chiffrement de grandes quantités de données, au moins parce que vous ne pouvez pas retrouver en sens inverse l'information en clair. Regardez dans les répertoires by-module/Crypt et by-module/PGP de votre miroir favori de CPAN pour trouver un grand nombre de modules potentiellement utiles.

dbmclose Image non disponible Image non disponible

 
Sélectionnez
dbmclose HACHAGE

Cette fonction brise le lien entre un fichier DBM (DataBase Management, gestion de base de données) et un hachage. dbmclose n'est en fait qu'un appel à untie avec les bons arguments, mais est fournie pour des raisons de compatibilité avec les anciennes versions de Perl.

dbmopen Image non disponible Image non disponible

 
Sélectionnez
dbmopen HACHAGE, NOMDB, MODE

Relie un fichier DBM à un hachage. (DBM signifie DataBase Management, gestion de base de données, et consiste en un ensemble de routines de bibliothèque C qui permettent un accès direct à des enregistrements via un algorithme de hachage.) HACHAGE est le nom de la base de données (sans l'extension .dir ou .pg). Si la base de données n'existe pas et qu'un MODE valide est spécifié, la base de données est créée avec les protections spécifiées par MODE, modifié par le umask. Pour empêcher la création de la base de données au cas où elle n'existe pas, il est possible de spécifier un mode valant undef, et la fonction renverra faux si elle ne peut trouver de base existante. Les valeurs associées au hachage avant le dbmopen ne sont plus accessibles.

La fonction dbmopen n'est en fait qu'un appel à tie avec les arguments appropriés, mais elle est fournie pour des raisons de compatibilité avec les anciennes versions de Perl. Vous pouvez contrôler quelle est bibliothèque DBM à utiliser en employant directement l'interface tie ou en chargeant le module approprié avant d'appeler open. Voici un exemple qui fonctionne sur certains systèmes pour les versions de DB_file similaires à celle de votre navigateur Netscape :

 
Sélectionnez
use Db_file;
dbmopen(%NS_hist, "$ENV{HOME}/.netscape/history.dat", undef)
    or die "Impossible d'ouvrir le fichier d'historique de netscape : $!";

while (($url, $quand) = each %NS_hist) {
    next unless defined($quand);
    chop ($url, $quand);    # supprime les octets nuls à fin
    printf "Dernière visite de %s le %s.\n", $url,
        scalar(localtime(unpack("V", $quand)));
}

Si vous n'avez pas d'accès au fichier DBM en écriture, vous pourrez seulement lire les variables du hachage sans les modifier. Pour tester si vous pouvez écrire, utilisez soit un test de fichier comme -w, soit essayez de modifier une entrée dans un hachage bidon à l'intérieur d'un eval {}, ce qui interceptera l'exception.

Les fonctions comme keys et values peuvent renvoyer une importante liste de valeurs lorsqu'on les utilise avec de grands fichiers DBM. Vous préférerez sans doute utiliser la fonction each pour les parcourir itérativement et ne pas tout charger d'un bloc en mémoire.

Les hachages liés à des fichiers DBM ont les mêmes limitations que le type de paquetage DBM que vous utilisez, notamment pour ce qui concerne la dimension de ce qu'on peut mettre dans une cellule (bucket). Si vous vous restreignez à des clefs et des valeurs courtes, cela ne constitue que rarement un problème. Voir aussi le module DB_file au chapitre 32.

Une autre chose dont il faut tenir compte est que de nombreuses bases de données DBM existantes contiennent des clefs et des valeurs terminées par un caractère nul, car elles ont été conçues pour être exploitées par des programmes C. Le fichier d'historique de Netscape et le fichier d'alias des anciens sendmail en sont des exemples. Il vous suffit d'utiliser "$key\0" lorsque vous extrayez une valeur, puis de supprimer le caractère nul dans cette dernière.

 
Sélectionnez
$alias = $les_alias{"postmaster\0"};
chop $alias;  # supprime le caractère nul

Il n'existe à l'heure actuelle aucun moyen intégré de verrouiller un fichier DBM générique. Certains pourraient considérer qu'il s'agit d'un bogue. Le module GDBM_file permet lui de verrouiller l'ensemble du fichier. En cas de doute, il vaut mieux utiliser un fichier verrou séparé.

defined Image non disponible

 
Sélectionnez
defined EXPR
defined

Cette fonction renvoie une valeur booléenne selon que EXPR contient une valeur définie ou non. La plupart des données que vous manipulez sont définies, mais un scalaire qui ne contient ni de chaîne valide, ni valeur numérique, ni de référence est considéré contenir la valeur indéfinie, ou pour abréger undef. Initialiser une variable scalaire à une valeur particulière la rendra définie et elle restera définie jusqu'à ce que vous lui assigniez une valeur indéfinie ou que vous appeliez explicitement undef avec cette variable comme paramètre.

De nombreuses opérations renvoient undef dans des conditions exceptionnelles, comme une fin de fichier, une variable non initialisée, une erreur système, etc. Puisque undef n'est qu'un type de valeur fausse, un simple test booléen ne fait pas de distinction entre undef, le chiffre zéro, la chaîne vide et la chaîne d'un seul caractère, « 0 » — toutes ces valeurs sont fausses de la même manière. La fonction defined vous permet de distinguer entre une chaîne vide indéfinie et une chaîne vide définie lorsque vous employez des opérateurs susceptibles de renvoyer une véritable chaîne vide.

Voici un morceau de code qui teste une valeur scalaire d'un hachage :

 
Sélectionnez
print if defined $option{D};

Lorsqu'on l'utilise sur un élément de hachage comme ceci, defined ne fait qu'indiquer si la valeur est définie, et non si la clef possède une entrée dans le hachage. Il est possible d'avoir une clef dont la valeur est indéfinie ; cependant la clef elle-même existe. Utilisez exist pour déterminer si une clef de hachage existe.

Dans l'exemple suivant, nous exploitons la convention qui fait que certaines opérations renvoient une valeur indéfinie lorsqu'il n'y a plus de données.

 
Sélectionnez
print "$val\n" while defined($val = pop(@tableau));

Et dans celui-ci, nous faisons la même chose avec la fonction getpwent pour obtenir des informations à propos des utilisateurs du système :

 
Sélectionnez
setpwent(); while (defined($nom = getpwent())) {
    print "< <$nom> >\n";
}
endpwent();

Il en va de même pour les erreurs renvoyées par les appels système qui peuvent légitimement renvoyer une valeur fausse :

 
Sélectionnez
die "readlink $sym impossible : $!"
    unless defined($valeur = readlink $sym);

Vous pouvez également utiliser defined pour déterminer si un sous-programme a d'ores et déjà été défini. Ceci évite de se surcharger avec des sous-programmes inexistants (ou des sous-programmes qui ont été déclarés, mais jamais définis) :

 
Sélectionnez
indirect("nom_fonction", @liste_args);
sub indirect {
    my $nom_routine = shift;
    no strict 'refs';      # ainsi nous pouvons utiliser
                           # nom_routine indirectement
    if (defined &$nom_routine) {
        &$nom_routine(@_); # ou $nom_routine->(@_);
    } else {
        warn "Appel ignoré à une fonction invalide $nom_routine";
    }
}

L'utilisation de defined sur les agrégats (hachages et tableaux) est dépréciée. (On l'utilisait pour savoir si la mémoire pour cet agrégat avait jamais été allouée.) À la place, employez un simple test booléen pour voir si le tableau ou le hachage possède des éléments :

 
Sélectionnez
if (@un_tableau) { print "tableau possédant des éléments\n";
if (%un_hachage) { print "hachage possédant des éléments\n";

Voir aussi undef et exists.

delete

 
Sélectionnez
delete EXPR

Cette fonction supprime un élément (ou une tranche d'éléments) dans le hachage ou le tableau spécifié. (Voir unlink si vous voulez supprimer un fichier.) Les éléments supprimés sont renvoyés dans l'ordre spécifié, bien que ce comportement ne soit pas garanti dans le cas de variables liées comme les fichiers DBM. Après la suppression, la fonction exists renverra faux pour toute clef ou indice supprimé. (À l'opposé, après la fonction undef, la fonction exists continue de renvoyer vrai, car la fonction undef ne fait que rendre indéfinie la valeur d'un élément, mais ne supprime pas l'élément lui-même.)

Supprimer dans le hachage %ENV modifie l'environnement. Les supprimer dans un hachage qui est lié à un fichier DBM (dans lequel on a les droits en écriture) supprime l'entrée dans ce fichier DBM.

Historiquement, vous pouviez seulement supprimer dans un hachage, mais avec Perl version 5.6 vous pouvez également supprimer dans un tableau. Une suppression dans un tableau a pour conséquence que l'élément à la position spécifiée retourne dans un état non initialisé, mais sans combler le vide, puisque ceci modifierait les positions de toutes les entrées suivantes. Utilisez un splice pour cela. (Toutefois, si vous supprimez le dernier élément d'un tableau, la taille de celui-ci diminuera de un — ou plus, selon la position de l'élément existant précédent s'il y en a.)

EXPR peut être arbitrairement complexe, pourvu que l'opération ultime soit une consultation de hachage ou de tableau :

 
Sélectionnez
# installation d'un tableau de tableau de hachage
$donjon[$x][$y] = \%proprietes;

# supprimer une propriété dans le hachage
delete $donjon[$x][$y]{OCCUPE}

# supprimer trois propriétés dans le hachage d'un seul coup
delete @{ $donjon[$x][$y] }{ "OCCUPE", "HUMIDE", "ECLAIRE" };

# supprimer la référence à %proprietes dans le tableau
delete $donjon[$x][$y];

L'exemple naïf qui suit supprime toutes les valeurs d'un %hachage de manière inefficace :

 
Sélectionnez
foreach $clef (keys %hachage) {
    delete $hachage{$clef};
}

De même que celui-ci :

 
Sélectionnez
delete @hachage{keys %hachage};

Mais ces deux exemples sont plus lents que si l'on assigne simplement au hachage la liste vide ou qu'on le rend indéfini :

 
Sélectionnez
%hachage = ();   # vide entièrement %hachage
undef %hachage;  # oublie que %hachage a jamais existé

Il en va de même pour les tableaux :

 
Sélectionnez
foreach $indice (0.. $#tableau) {
    delete $tableau[$indice];
}

et :

 
Sélectionnez
delete @tableau[0 .. $#tableau];

sont moins efficaces que :

 
Sélectionnez
@tableau = ();   # vide entièrement @tableau
undef @tableau;  # oublie que @tableau a jamais existé

die Image non disponible

 
Sélectionnez
die LISTE
die

Hors d'un eval, cette fonction affiche la valeur concaténée de LISTE sur STDERR et sort avec la valeur courante de $! (la variable errno de la bibliothèque C). Si $! vaut 0, elle sort avec la valeur de $? >> 8 (qui est le statut du dernier fils récolté depuis un system, un wait, un close sur un pipe, ou une `commande`). Si $? >> 8 vaut 0, elle sort avec 255.

À l'intérieur d'un eval, la fonction met le message d'erreur qui aurait autrement été produit dans la variable $@, puis elle interrompt le eval, qui renvoie undef. La fonction die peut ainsi être utilisée pour lever des exceptions nommées susceptibles d'être exploitées à un plus haut niveau dans le programme. Voir eval plus loin dans ce chapitre.

Si LISTE est une référence vers un objet unique, cet objet est supposé être un objet exception et il est renvoyé sans modification comme l'exception dans $@.

Si LISTE est vide et que $@ contient déjà une chaîne (provenant généralement d'un précédent eval), cette chaîne est réutilisée en lui ajoutant "\t...propagated". Ceci est utile pour propager (lever à nouveau) des exceptions :

 
Sélectionnez
eval { ... };
die unless $@ =~ /Exception attendue/;

Si LISTE est vide et que $@ contient déjà un objet exception, la méthode $@->PROPAGATE est appelée pour déterminer comment l'exception doit être propagée.

Si LISTE est vide ainsi que $@, la chaîne "Died" est utilisée.

Si la valeur finale de LISTE ne se termine pas par un saut de ligne (et que vous ne passez pas d'objet exception), le nom du script courant, le numéro de ligne et le numéro de ligne du fichier d'entrée (s'il existe) sont ajoutés au message, ainsi qu'un saut de ligne. Astuce : quelquefois, le fait d'ajouter ", stopped" à votre message le rendra plus explicite quand la chaîne "at nom_de_script line 123" lui sera ajoutée. Supposons que vous lanciez le script canasta ; considérez la différence entre les deux manières suivantes de mourir :

 
Sélectionnez
die "/usr/games ne vaut rien";
die "/usr/games ne vaut rien, stopped";

qui produisent respectivement :

 
Sélectionnez
/usr/games ne vaut rien at canasta line 123.
/usr/games ne vaut rien, stopped at canasta line 123.

Si vous désirez que vos propres messages donnent le nom de fichier et le numéro de ligne, employez les tokens spéciaux __FILE__ et __LINE__ :

 
Sélectionnez
die '"', __FILE__, '", ligne ', __LINE__, ", hou la honte !\n";

La sortie ressemblera alors à :

 
Sélectionnez
"canasta", ligne 38, hou la honte !

Une autre question de style — considérez les exemples équivalents suivants :

 
Sélectionnez
die "Impossible de faire un cd vers le spool : $!\n"
    unless chdir '/usr/spool/news';
chdir '/usr/spool/news'
    or die "Impossible de faire un cd vers le spool : $!\n";

Comme la partie importante est le chdir, on préfère généralement la seconde forme. Voir également exit, warm, %SIG et le module Carp.

do (bloc)

 
Sélectionnez
do BLOC

La forme do BLOC exécute la séquence de commandes indiquée par BLOC et renvoie la valeur de la dernière expression évaluée dans le bloc. Lorsqu'elle est modifiée par une instruction while ou until, Perl exécute le BLOC une fois avant de tester la condition de sortie. (Pour d'autres instructions, les modificateurs de boucle testent la condition en premier.) Le do BLOC lui-même ne compte pas comme une boucle, ainsi les instructions de contrôle de boucle next, last ou redo ne peuvent pas être utilisées pour quitter ou recommencer le bloc. Voir la section Blocs simples au chapitre 4, Instruction et déclaration, pour contourner ce problème.

do (fichier) Image non disponible

 
Sélectionnez
do FICHIER

La forme do FICHIER utilise la valeur de FICHIER comme nom de fichier et exécute son contenu comme un script Perl. Son usage premier est (ou plutôt était) d'inclure des sous-programmes depuis une bibliothèque Perl, de sorte que :

 
Sélectionnez
do 'stat.pl';

est identique à :

 
Sélectionnez
scalar eval 'cat stat.pl'; #'type stat.pl' sur Windows

sauf que la première forme est plus efficace, plus concise, elle garde la trace du nom de fichier courant pour les messages d'erreur, cherche dans tous les répertoires du tableau @INC et met à jour %INC si le fichier est trouvé. (Voir au chapitre 28, Noms spéciaux.) Elle diffère également dans le fait que le code évalué avec do FICHIER ne peut pas voir les variables lexicales dans la portée qui l'englobe, à l'inverse du code dans eval FICHIER. Mais elle est pourtant similaire à la seconde en ce qu'elle rescrute le fichier à chaque appel, et il vaut mieux ne pas l'employer dans une boucle à moins que le nom du fichier lui-même change à chaque itération.

Si do ne peut pas lire le fichier, elle renvoie undef et met l'erreur dans $!. Si do peut lire le fichier, mais pas le compiler, elle retourne undef et met un message d'erreur dans $@. Si le fichier est compilé avec succès, do renvoie la valeur de la dernière expression évaluée.

L'inclusion de modules de bibliothèques (qui ont obligatoirement un suffixe .pm) est mieux gérée par les opérateurs use et require, qui contrôlent les erreurs et génèrent une exception s'il y a un problème. Ils ont également d'autres avantages : ils évitent de dupliquer le chargement, facilitent la programmation orientée objet et fournissent des indications au compilateur sur les prototypes de fonctions.

Mais do FICHIER est toujours utile pour des choses comme la lecture de fichiers de configuration. On peut faire un contrôle d'erreur manuel comme ceci :

 
Sélectionnez
# lit dans les fichiers de configuration : système d'abord,
# ensuite utilisateur
for $fichier ("/usr/share/projet/defaut.rc",
              "$ENV{HOME}/.programmerc")
{
    unless ($retour = do $fichier) {
        warn "Impossible de scruter $fichier : $@"  if $@;
        warn "Impossible de faire do $fichier : $!" unless defined $retour;
        warn "Impossible de lancer $fichier"        unless $retour;
    }
}

Un démon qui doit tourner longtemps peut périodiquement examiner la date de son fichier de configuration, et si le fichier a été modifié depuis sa dernière lecture, le démon peut utiliser do pour recharger le fichier. Il est plus propre de le faire avec do qu'avec require ou use.

do (sous-programme) Image non disponible

 
Sélectionnez
do SOUS-PROGRAMME(LISTE)

La forme do SOUS-PROGRAMME(LISTE) est une forme dépréciée d'appel d'un sous-programme. Une exception est levée si le SOUS-PROGRAMME n'est pas défini. Voir le chapitre 6, Sous-programmes.

dump

 
Sélectionnez
dump LABEL
dump

Cette fonction provoque un core dump immédiat. En premier lieu, ceci vous permet d'utiliser le programme undump(1) (non fourni) pour transformer le fichier de copie résultant en un binaire exécutable après avoir initialisé toutes les variables au début du programme. Quand le nouveau binaire sera exécuté, il commencera par un goto LABEL (avec toutes les restrictions inhérentes à goto). On peut voir le processus complet comme un saut inconditionnel avec un core dump, suivi d'une réincarnation. Si LABEL est omis, le programme repart du début. Attention : tout fichier ouvert au moment de la copie avec dump, ne le sera plus au moment de la réincarnation du programme, d'où une possible confusion de la part de Perl. Voyez également l'option de ligne de commande -u au chapitre 19, Interface de la ligne de commande.

Cette fonction est maintenant tout à fait obsolète, en partie parce qu'il est extrêmement difficile de convertir un core dump en un binaire dans le cas général, et parce que les divers compilateurs générant du bytecode portable ou du C compilable l'ont surpassé.

Si vous désirez utiliser dump pour accélérer vos programmes, allez voir la discussion concernant les questions d'efficacité au chapitre 24, Usage courant, ainsi que le compilateur en code natif au chapitre 18, Compilation. L'autochargement peut également présenter un certain intérêt, en ce qu'il semble accélérer l'exécution.

each

 
Sélectionnez
each HACHAGE

Cette fonction parcourt pas à pas un hachage à raison d'une paire clef/valeur à la fois. Appelée dans un contexte de liste, each renvoie une liste à deux éléments composée de la clef et de la valeur de l'entrée suivante d'un hachage, il vous est ainsi possible de circuler dans la liste toute entière. Appelée dans un contexte scalaire, each renvoie seulement la clef de l'entrée suivante du hachage. Quand le hachage est entièrement lu, elle renvoie la liste vide, qui produit une valeur fausse lorsqu'elle est assignée dans un contexte scalaire, comme un test de boucle. L'appel suivant à each redémarrera une nouvelle itération. On l'utilise généralement comme dans l'exemple suivant qui utilise le hachage prédéfini %ENV :

 
Sélectionnez
while (($clef, $valeur) = each %ENV) {
    print "$clef=$valeur\n";
}

En interne, un hachage conserve ses entrées dans un ordre apparemment aléatoire. La fonction each boucle le long de cette séquence, car chaque hachage se souvient de l'entrée renvoyée en dernier. L'ordre réel de cette séquence est susceptible de changer dans les prochaines versions de Perl, mais il est garanti qu'il sera identique à celui que renverrait la fonction keys (ou values) avec le même hachage (sans modification).

Il existe un itérateur unique pour chaque hachage, partagé par tous les appels aux fonctions each, keys et values du programme ; on peut le remettre à zéro en lisant tous les éléments du hachage, ou en évaluant keys %hachage ou values %hachage. Si vous ajoutez ou supprimez des éléments d'un hachage pendant qu'il y a une itération sur celui-ci, les conséquences ne sont pas bien définies : des entrées peuvent être passées ou dupliquées.

Voir aussi keys, values et sort.

eof Image non disponible

 
Sélectionnez
eof HANDLE_FICHIER
eof()
eof

Cette fonction renvoie vrai si la lecture suivante sur HANDLE_FICHIER renverra une fin de fichier, ou si HANDLE_FICHIER n'est pas ouvert. HANDLE_FICHIER peut être une expression dont la valeur donne le vrai nom du handle de fichier. Un eof sans argument renvoie le statut de fin de fichier pour le dernier fichier lu. Un eof() avec des parenthèses vides teste le handle de fichier ARGV (plus généralement rencontré en tant que handle de fichier nul dans <>). Ainsi, à l'intérieur d'une boucle while (<>), un eof() avec parenthèses ne détectera la fin que du dernier d'un groupe de fichiers. Utilisez eof (sans parenthèses) pour tester chacun des fichiers dans une boucle while (<>). Par exemple le code suivant insère des tirets juste avant la dernière ligne du dernier fichier :

 
Sélectionnez
while (<>) {
    if (eof()) {
        print "-" x 30, "\n";
    }
    print;
}

Pour sa part, ce script remet à zéro la numérotation des lignes pour chaque fichier d'entrée :

 
Sélectionnez
# remet à zéro la numérotation des lignes pour chaque fichier d'entrée
while (<>) {
    next if /^\s*#/;    # passe les commentaires
    print "$.\t$_";
} continue {
    close ARGV if eof;  # Et non eof() !
}

De même que « $ » dans un programme sed, eof brille particulièrement dans les numérotations de lignes par zones. Voici un script qui affiche les lignes de /motif/ à la fin de chaque fichier d'entrée :

 
Sélectionnez
while (<>) {
    print if /motif/ .. eof;
}

Ici, l'opérateur de bascule (..) évalue la correspondance du motif à chaque ligne. Jusqu'à ce que le motif corresponde, l'opérateur renvoie faux. Quand la correspondance est enfin trouvée, l'opérateur commence par renvoyer vrai, provoquant ainsi l'affichage des lignes. Quand l'opérateur eof renvoie finalement vrai (à la fin du fichier examiné), l'opérateur de bascule se remet à zéro et renvoie de nouveau faux pour le prochain fichier dans @ARGV.

Attention : la fonction eof lisant un octet puis le remettant dans le flux d'entrée avec ungetc(3), elle n'est pas très utile dans un contexte interactif. En fait, les programmeurs Perl expérimentés utilisent rarement eof, puisque les divers opérateurs d'entrée se comportent plutôt bien dans les expressions conditionnelles des boucles while. Reportez-vous à l'exemple de la description de foreach au chapitre 4.

eval Image non disponible Image non disponible

 
Sélectionnez
eval BLOC
eval EXPR
eval

Le mot-clef eval dessert en Perl deux buts différents, mais néanmoins liés. Ces buts sont représentés par deux formes de syntaxe, eval BLOC et eval EXPR. La première forme intercepte les exceptions à l'exécution (erreurs) qui auraient sinon provoqué une erreur fatale, de la même manière qu'un « bloc try » en C++ ou en Java. La seconde forme compile et exécute de petits morceaux de code à la volée et intercepte également (et c'est bien commode) les exceptions exactement comme la première forme. Mais la seconde forme s'exécute beaucoup plus lentement que la première, puisqu'elle doit analyser la chaîne à chaque fois. D'un autre côté, elle est aussi plus générique. Quelle que soit la forme que vous utilisez, eval est la manière standard d'intercepter les exceptions en Perl.

Pour chacune des formes, la valeur renvoyée par eval est celle de la dernière expression évaluée, tout comme dans un sous-programme. Vous pouvez de même utiliser l'opérateur return pour renvoyer une valeur au beau milieu de l'eval. L'expression générant la valeur de retour est évaluée dans un contexte vide, scalaire ou de liste, selon le contexte de l'eval lui-même. Voir wantarray pour plus d'informations sur la manière de déterminer un contexte.

S'il se produit une erreur interceptable (y compris une erreur engendrée par l'opérateur die), eval renvoie undef et met le message d'erreur (ou l'objet) dans $@. S'il n'y a pas d'erreur, $@ est garantie contenir la chaîne vide, vous pouvez ainsi détecter les erreurs après coup de manière fiable. Un simple test booléen suffit.

 
Sélectionnez
eval { ... };    # intercepte les erreurs à l'exécution
if ($@) { ... }  # gère les erreurs

La forme eval BLOC est vérifiée syntaxiquement durant la compilation, ce qui la rend assez performante. (Cela trouble de temps à autre les personnes habituées à la forme lente eval EXPR.) Puisque le code du BLOC est évalué à la compilation en même temps que le code qui l'entoure, cette forme d'eval ne peut pas intercepter les erreurs de syntaxe.

La forme eval EXPR peut quant à elle intercepter les erreurs syntaxiques, car elle analyse le code durant l'exécution. (Si l'analyse échoue, elle met l'erreur analysée dans $@, comme d'habitude.) Sinon, elle exécute la valeur de EXPR comme si c'était un petit programme Perl. Le code est exécuté dans le contexte courant du programme Perl, ce qui signifie qu'il peut voir toutes les variables lexicales de la portée qui l'englobe, tout comme les définitions de sous-programmes ou de formats. Le code de l'eval est traité en tant que bloc, toute variable de portée locale déclarée à l'intérieur de l'eval n'existe donc que le temps de l'eval. (Voir my et local.) Comme dans tout code à l'intérieur d'un bloc, il n'y a pas besoin de point-virgule à la fin.

Voici un simple script Perl. Il demande à l'utilisateur d'entrer une chaîne arbitraire de code Perl, la compile, l'exécute et affiche les éventuelles erreurs qui se sont produites :

 
Sélectionnez
print "\nEntrer du code Perl : ";

while (<STDIN>) {
    eval;
    print $@;
    print "\nEntrer à nouveau du code Perl : ";
}

Voici un programme rename pour changer le nom d'une quantité de fichiers en utilisant une expression Perl :

 
Sélectionnez
#!/usr/bin/perl
# rename -change les noms des fichiers
$op = shift;
for (@ARGV) {
    $ancien = $_;
    eval $op;
    die if $@;
    # la prochaine ligne appelle la fonction interne Perl,
    # non le script du même nom
    rename($ancien, $_) unless $ancien eq $_;
}

Vous pouvez utiliser ce programme comme ceci :

 
Sélectionnez
$ rename 's/\.orig$//'               *.orig
$ rename 'y/A-Z/a-z/ unless /^Make/' *
$ rename '$_ .= ".bad"'              *.f

Puisqu'eval intercepte des erreurs qui sinon seraient fatales, il est très utile pour déterminer si une fonctionnalité donnée (comme fork ou symlink) est implémentée.

Comme un eval BLOC est vérifié syntaxiquement à la compilation, toute erreur de syntaxe est reportée en amont. Ainsi, si votre code est invariant et qu'à la fois un eval EXPR et un eval BLOC vous conviennent, la dernière forme est la meilleure. Par exemple :

 
Sélectionnez
# rend la division par zéro non fatale
eval { $reponse = $a / $b; };       warn $@ if $@;

# idem, mais moins performant si on l'exécute plusieurs fois
eval '$reponse = $a / $b';          warn $@ if $@;

# une erreur de syntaxe à la compilation (non interceptée)
eval { $reponse = };                # MAUVAIS

# une erreur de syntaxe à l'exécution
eval '$reponse =';                  # positionne $@

Ici, le code du BLOC doit être un code Perl valide pour passer la phase de compilation. Le code de l'EXPR n'est pas examiné avant l'exécution, il ne produit donc pas d'erreur avant d'être exécuté.

Le bloc d'un evalBLOCK ne compte pas comme une boucle, ainsi les instructions de contrôle de boucle next, last et redo ne peuvent pas être employées pour sortir ou recommencer le bloc.

exec Image non disponible Image non disponible

 
Sélectionnez
exec CHEMIN LISTE
exec LISTE

La fonction exec termine le programme courant, exécute une commande externe et n'en revient jamais !!! Utilisez system au lieu de exec si vous voulez reprendre le contrôle après la la fin de la commande. La fonction exec échoue et renvoie faux seulement si la commande n'existe pas et si elle est exécutée directement et non par l'intermédiaire d'une commande shell de votre système (nous en discuterons plus loin).

S'il n'y a qu'un seul argument scalaire, celui-ci est inspecté pour y chercher des métacaractères du shell. S'il y en a, l'argument est tout entier passé à l'interpréteur de commandes standard du shell (/bin/sh sous Unix). Sinon, l'argument est décomposé en mots et exécuté directement dans un souci d'efficacité, puisqu'on économise ainsi la surcharge due au traitement du shell. Cela vous donne également plus de contrôle sur la reprise d'erreur si jamais le programme n'existait pas.

S'il y a plus d'un argument dans la LISTE, ou si LISTE est un tableau avec plus d'une valeur, le shell du système ne sera jamais utilisé. Ceci évite également tout traitement de la commande par le shell. La présence ou l'absence de métacaractères dans les arguments n'affecte pas ce comportement déclenché par la liste, ce qui en fait la forme idéale pour des programmes soucieux de la sécurité, ne voulant pas s'exposer à des fuites potentielles dans le shell.

Cet exemple entraîne le remplacement du programme Perl en train de tourner par le programme echo, qui affiche la liste d'arguments courante :

 
Sélectionnez
exec 'echo', 'Vos arguments sont :', @ARGV;

Cet autre exemple montre que vous pouvez executer un pipeline et non uniquement un seul programme :

 
Sélectionnez
exec "sort $fichier_sortie | uniq"
    or die "Impossible de faire un sort/uniq : $!\n";

exec ne revient généralement jamais — si c'est le cas, il retourne toujours faux et vous devez vérifier $! pour savoir ce qui s'est mal passé. Remarquez que dans les anciennes versions de Perl, exec (et system) ne vidaient pas votre tampon de sortie, vous deviez donc activer le vidage du tampon de commande en positionnant $| sur un ou plusieurs handles de fichier pour éviter la perte de la sortie dans le cas d'exec, ou une sortie désordonnée dans le cas de system. La version 5.6 de Perl remédie largement à cette situation.

Lorsque vous demandez au système d'exploitation d'exécuter un nouveau programme à l'intérieur d'un processus existant (comme le fait la fonction exec de Perl), vous indiquez au système où se trouve le nouveau programme à exécuter, mais vous donnez aussi au nouveau programme (à travers son premier argument) le nom sous lequel il a été invoqué. Habituellement, le nom que vous donnez est juste une copie de l'endroit où se trouve le programme, mais vous n'y êtes pas nécessairement obligés, puisqu'il y a deux arguments distincts au niveau du langage C. Lorsqu'il ne s'agit pas d'une copie, vous obtenez comme curieux résultat que le nouveau programme croit qu'il est lancé sous un nom qui peut être complètement différent du véritable chemin dans lequel il réside. Cela n'a souvent pas de conséquences pour le programme en question, mais certains programmes y font attention et adoptent une personnalité différente selon ce qu'ils pensent être leur nom. Par exemple, l'éditeur vi regarde s'il a été appelé avec « vi » ou avec « view ». S'il a été invoqué avec « view », il se met automatiquement en mode lecture seule, exactement comme s'il avait été appelé avec l'option de la ligne de commande -R.

Voilà où le paramètre optionnel CHEMIN de exec entre en jeu. Syntaxiquement, il vient se brancher sur la position d'un objet indirect comme le handle de fichier pour print ou printf. Ainsi, il n'y a pas de virgule après lui, car il ne fait pas exactement partie de la liste d'arguments. (En un sens, Perl adopte l'approche opposée du système d'exploitation en ce qu'il suppose que le premier argument est le plus important et qu'il vous laisse modifier le chemin s'il diffère.) Par exemple :

 
Sélectionnez
$editeur = "/usr/bin/vi";
exec $editeur "view", @fichiers   # active le mode lecture seule
    or die "Impossible d'exécuter $editeur : $!\n";

Comme avec tout objet indirect, vous pouvez également remplacer le simple scalaire contenant le nom du programme avec un bloc contenant du code arbitraire, ce qui simplifie l'exemple précédent en donnant :

 
Sélectionnez
exec { "/usr/bin/vi" } "view" @fichiers  # active le mode lecture seule
    or die "Impossible d'exécuter /usr/bin/vi : $!\n";

Comme nous l'avons déjà évoqué, exec traite une liste discrète d'arguments comme une indication qu'il doit éviter le traitement du shell. Toutefois, il y a un endroit où vous pourriez être déroutés. L'appel exec (et également system) ne distingue pas un unique argument scalaire d'un tableau ne contenant qu'un seul élément.

 
Sélectionnez
@args = ("echo surprise");  # une liste à un seul élément
exec @args                  # toujours sujet aux fuites du shell
    or die "exec : $!\n";   #, car @args == 1

Pour éviter ceci, vous pouvez utiliser la syntaxe avec CHEMIN, en dupliquant exactement le premier argument dans le chemin, ce qui force l'interprétation du reste des arguments à être une liste, même s'il n'y en a qu'un seul :

 
Sélectionnez
exec { args[0] } @args      # sécurisé même si la liste n'a qu'un argument
    or die "exec @args impossible : $!";

La première version, celle avec les parenthèses, lance le programme echo en lui passant « surprise » comme argument. La seconde version ne fait pas la même chose — elle tente de lancer un programme appelé littéralement echo surprise, ne le trouve pas (du moins on l'espère) et positionne $! à une valeur non nulle indiquant l'échec.

Comme la fonction exec est le plus souvent utilisée peu après un fork, on suppose que l'on doit passer outre tout ce qui survient normalement lorsqu'un processus Perl se termine. Sous un exec, Perl n'appellera pas les blocs END, ni les méthodes DESTROY associées aux objets. Sinon, vos processus fils se termineraient en faisant le nettoyage alors que vous vous attendiez à ce que ce soit le processus parent qui le fasse. (Nous aimerions que ce soit le cas dans la vie réelle.)

Comme c'est une erreur courante d'utiliser exec au lieu de system, Perl vous en avertit si la prochaine instruction n'est pas die, warn ou exit, lorsqu'il est lancé avec l'option populaire de la ligne de commande -w, ou si vous employez le pragma use warnings qw(exec syntax). Si vous voulez vraiment faire suivre un exec d'une autre instruction, vous pouvez utiliser l'un ou l'autre de ces styles pour éviter l'avertissement :

 
Sélectionnez
exec ('machin')   or print STDERR "exec machin impossible : $!";
{ exec ('machin') }; print STDERR "exec machin impossible : $!";

Comme dans la seconde ligne ci-dessus, un appel à exec qui est la dernière instruction dans un bloc est exempt de cet avertissement.

Voir aussi system.

exists

 
Sélectionnez
exists EXPR

Cette fonction renvoie vrai si la clef de hachage ou l'indice de tableau spécifié existe dans le hachage ou le tableau. Peu importe que la valeur correspondante soit vraie ou fausse, ou même qu'elle soit définie.

 
Sélectionnez
print "Vraie\n"   if         $hachage{$clef};
print "Définie\n" if defined $hachage{$clef};
print "Existe\n"  if exists  $hachage{$clef};
print "Vrai\n"    if         $tableau[$indice];
print "Défini\n"  if defined $tableau[$indice];
print "Existe\n"  if exists  $tableau[$indice];

Un élément ne peut être vrai que s'il est défini, et ne peut être défini que s'il existe, mais l'inverse n'est pas forcément valable.

EXPR peut être arbitrairement complexe, tant que l'opération finale est une consultation de clef de hachage ou d'indice de tableau.

 
Sélectionnez
if (exists $hachage{A}{B}{$clef}) { ... }

Bien que le dernier élément ne vienne pas à exister spontanément seulement parce qu'on a testé son existence, c'est le cas de ceux que l'on fait intervenir. Ainsi, $$hachage{"A"} et $hachage{"A"}->{"B"} se mettent tous deux à exister. Ce n'est pas une fonctionnalité de exists en soi ; cela se produit partout où l'opérateur flèche est utilisé (explicitement ou implicitement) :

 
Sélectionnez
undef $ref if (exists $ref->"Une clef"}) { }
print $ref; # affiche HASH(0x80d3d5c)

Même si l'élément "Une clef" ne se met pas à exister, la variable $ref, indéfinie auparavant, vient tout à coup contenir un hachage anonyme. C'est une instance surprise d'autovivification de ce qui n'apparaissait pas au premier — ou même au second — coup d'œil comme un contexte lvalue. Ce comportement sera agréablement corrigé dans une prochaine version. Autrement, vous pouvez emboîter vos appels :

 
Sélectionnez
if ($ref and exists $ref->[$x] and
exists $ref->[$x][$y] and
exists $ref->[$x][$y]{$clef} and
exists $ref->[$X][$y]{$clef}[2] ) { }

Si EXPR est le nom d'un sous-programme, la fonction exists renverra vrai si celui-ci est a été déclaré, même s'il n'a pas encore été défini. L'exemple suivant affiche seulement « Existe » :

 
Sélectionnez
sub couic;
print "Existe\n" if exists &couic;
print "Défini\n" if defined &couic;

L'utilisation d'exists avec le nom d'un sous-programme peut être utile pour un sous-programme AUTOLOAD qui a besoin de savoir si un paquetage particulier veut qu'un sous-programme particulier soit défini. Le paquetage peut indiquer ceci en déclarant un entête de sub comme couic.

exit

 
Sélectionnez
exit EXPR
exit

Cette fonction évalue EXPR comme un entier et sort immédiatement avec cette valeur comme statut d'erreur final du programme. Si EXPR est omise, la fonction sort avec le statut 0 (signifiant « aucune erreur »). Voici un fragment qui permet à un utilisateur de sortir du programme en entrant x ou X.

 
Sélectionnez
$rep = <STDIN>;
exit if $rep =~ /^[Xx]/;

Vous ne devriez pas utiliser exit pour quitter un sous-programme s'il y a la moindre chance que quelqu'un veuille intercepter l'erreur qui s'est produite. Utilisez plutôt die, qui peut être intercepté par un eval. Ou alors, utilisez l'une des sur-couches de die du module Carp, comme croak ou confess.

Nous avons dit que la fonction exit sortait immédiatement, mais c'était un mensonge d'arracheur de dents. Elle sort aussitôt que possible, mais elle appelle tout d'abord les routines END définies afin les gérer les événements de fin (N.d.T. : at-exit). Ces routines ne peuvent pas annuler la terminaison, bien qu'elles puissent changer la valeur de retour éventuelle en positionnant la variable $?. De la même manière, toute classe qui définit une méthode DESTROY peut invoquer cette méthode au nom de tous ses objets avant que le programme réel ne finisse. Si vous avez vraiment besoin d'outrepasser le traitement avant la terminaison, vous pouvez appeler les fonctions _exit du module POSIX pour éviter toutes les opérations de END et des destructeurs. Et si POSIX n'est pas disponible, vous pouvez faire un exec "/bin/false" ou quelque chose de ce genre.

exp Image non disponible

 
Sélectionnez
exp EXPR
exp

Cette fonction renvoie e à la puissance EXPR. Pour obtenir la valeur de e, utilisez juste exp(1). Pour effectuer une exponentiation générale de différentes bases, utilisez l'opérateur ** que nous avons emprunté au FORTRAN :

 
Sélectionnez
use Math::Complex;
print -exp(1) ** (i * pi); # affiche 1

fcntl Image non disponible Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
fcntl HANDLE_FICHIER, FONCTION, SCALAIRE

Cette fonction appelle les fonctions de contrôle de fichier de votre système d'exploitation, documentées dans la page de man de fnctl(2). Avant d'appeler fcntl, vous devrez probablement tout d'abord écrire :

 
Sélectionnez
use Fcntl;

pour charger les définitions correctes des constantes.

SCALAIRE sera lu ou écrit (ou les deux) selon la FONCTION. Un pointeur sur la valeur de chaîne de SCALAIRE sera passé comme troisième argument de l'appel véritable à fcntl. (Si SCALAIRE n'a pas de valeur chaîne, mais une valeur numérique, celle-ci sera passée directement au lieu d'un pointeur sur la valeur chaîne.) Voir le module Fcntl pour une description des valeurs les plus communes qu'il est possible d'employer pour FONCTION.

La fonction fcntl lèvera une exception si elle est utilisée sur un système qui n'implémente pas fcntl(2). Sur les systèmes qui au contraire l'implémentent, vous pouvez faire des choses comme modifier les flags close-on-exec (si vous ne désirez pas jouer avec la variable $^F ($SYSTEM_FD_MAX)), modifier les flags d'entrées/sorties non bloquantes, émuler la fonction lockf (3) ou s'arranger pour recevoir un signal SIGIO lorsqu'il y a des entrées/sorties en attente.

Voici un exemple où l'on rend non bloquant au niveau du système, un handle de fichier nommé DISTANT. Ceci fait que toute opération d'entrée revient immédiatement si rien n'est disponible lors d'une lecture dans un pipe, une socket ou une ligne série qui autrement aurait bloqué. De même, les opérations de sortie qui bloqueraient normalement, renvoient un statut d'échec à la place. (Pour celles-ci, vous feriez mieux de négocier également $|.)

 
Sélectionnez
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);

$flags = fcntl(DISTANT, F_GETFL, 0)
            or die "Impossible de lire les flags pour la socket : $!\n";
$flags = fcntl(DISTANT, F_SETFL, $flags | O_NONBLOCK)
            or die "Impossible de modifier les flags de la sockets : $!\n";

La valeur de retour de fcntl (et de ioctl) se comporte comme ceci :

L'appel système renvoie

Perl renvoie

-1

undef.

0

La chaîne « 0 but true ».

autre chose

Le même nombre.

Perl rend donc vrai pour un succès et faux pour un échec, tout en vous laissant facilement déterminer la véritable valeur renvoyée par le système d'exploitation :

 
Sélectionnez
$valret = fcntl() || -1;
printf "fcntl a vraiment renvoyé %d\n", $valret;

Ici, même la chaîne « 0 but true » affiche 0, grâce au format %d. Cette chaîne est vraie dans un contexte booléen et 0 dans un contexte numérique. (Par bonheur, elle est également exempte des avertissements habituels pour les conversions numériques inadaptées.)

fileno Image non disponible

 
Sélectionnez
fileno HANDLE_FICHIER

Cette fonction renvoie le descripteur de fichier sous-jacent d'un handle de fichier. Si ce handle de fichier n'est pas ouvert, fileno renvoie undef. Un descripteur de fichier est un petit entier positif comme 0 ou 1, alors que les handles de fichiers comme STDIN ou STDOUT sont des symboles. Malheureusement, le système d'exploitation ne connaît pas vos sympathiques symboles. Il ne pense aux fichiers ouverts qu'en terme de ces petits numéros de fichiers et bien que Perl fasse automatiquement la traduction pour vous, vous devrez parfois connaître le véritable descripteur de fichier.

Par exemple, la fonction fileno est utile pour construire des masques de bits pour select et pour passer certains appels système obscurs si syscall(2) est implémenté. Elle sert également à vérifier que la fonction open vous a donné le descripteur de fichier que vous vouliez et également à déterminer si deux handles de fichiers utilisent le même descripteur de fichier système.

 
Sélectionnez
if (fileno(CECI) == fileno(CELA)) {
    print "CECI et CELA sont des duplicata\n";
}

Si HANDLE_FICHIER est une expression, sa valeur est prise comme un handle de fichier indirect, généralement son nom ou une référence à quelque chose qui ressemble à un objet handle de fichier.

Attention : ne comptez pas sur une association entre un handle de fichier Perl et un descripteur de fichier numérique qui soit permanente tout au long de la vie du programme. Si un fichier a été fermé et rouvert, le descripteur de fichier peut changer. Perl s'efforce d'assurer que certains descripteurs de fichiers ne sont pas perdus si un open sur eux échoue, mais il ne fait cela que pour les descripteurs de fichiers qui ne dépassent pas la valeur courante de la variable spéciale $^F ($SYSTEM_MAX_FD) (par défaut, 2). Bien que les handles de fichiers STDIN, STDOUT et STDERR démarrent avec les descripteurs de fichiers 0, 1 et 2 (la convention standard Unix), même ceux-ci peuvent changer si vous commencez à les fermer et les ouvrir sans prendre garde. Ceci dit, vous ne pouvez pas avoir d'ennuis avec 0, 1 et 2 aussi longtemps que vous les rouvrez toujours immédiatement après les avoir fermés. La règle de base sur les systèmes Unix est de prendre le descripteur disponible le plus bas possible, et ce sera celui que vous venez juste de fermer.

flock Image non disponible Image non disponible Image non disponible

 
Sélectionnez
flock HANDLE_FICHIER, OPÉRATION

La fonction flock est l'interface portable de Perl pour le verrouillage de fichiers, bien qu'elle ne verrouille un fichier que dans son intégralité et non des enregistrements. La fonction gère les verrous sur le fichier associé à HANDLE_FICHIER, en renvoyant vrai pour un succès et faux sinon. Pour éviter la possibilité de perdre des données, Perl vide le tampon de votre HANDLE_FICHIER avant de le verrouiller ou de le déverrouiller. Perl peut implémenter son flock avec flock(2), fcntl(2), lockf (3) ou des mécanismes de verrouillage spécifiques à d'autres plates-formes, mais si aucun d'entre eux n'est disponible, appeler flock lève une exception. Voir la section Verrouillage de fichier au chapitre 16.

OPÉRATION peut valoir LOCK_SH, LOCK_EX ou LOCK_UN, combinés éventuellement par un OU avec LOCK_NB. Ces constantes valent généralement 1, 2, 8 et 4, mais vous pouvez employer les noms symboliques si vous les importez depuis le module Fcntl, soit individuellement, soit par groupe en utilisant le tag :flock.

LOCK_SH demande un verrou partagé, il est donc généralement utilisé pour les lectures. LOCK_EX demande un verrou exclusif, il est donc généralement utilisé pour les écritures. LOCK_UN relâche un verrou demandé auparavant ; fermer le fichier relâche également ses verrous. Si le bit LOCK_NB est employé avec LOCK_SH ou LOCK_EX, flock rend la main immédiatement au lieu d'attendre un verrou indisponible. Vérifiez le statut de retour pour voir si vous avez obtenu le verrou que vous avez demandé. SI vous n'utilisez pas LOCK_NB, vous pouvez attendre indéfiniment l'accès au verrou.

Un autre aspect difficile, mais général, de flock est que ses verrous sont simplement consultatifs. Les verrous discrets sont plus flexibles, mais offrent moins de garanties que les verrous obligatoires. Cela signifie que les fichiers verrouillés avec flock peuvent être modifiés par les programmes qui n'utilisent pas flock. Les voitures qui s'arrêtent aux feux rouges s'entendent bien entre elles, mais pas avec celles qui ne s'arrêtent pas aux feux rouges. Conduisez sur la défensive.

Certaines implémentations de flock ne peuvent pas verrouiller quoique ce soit à travers un réseau. Bien qu'en théorie vous puissiez utiliser fcntl, plus spécifique au système, pour cela, le jury (ayant délibéré sur le cas pendant à peu près une décennie) est toujours indécis pour déterminer si c'est une chose digne de confiance ou non.

Voici un exemple qui ajoute un message à la fin d'une boîte aux lettres sur les systèmes Unix qui utilisent flock(2) pour verrouiller les boîtes aux lettres :

 
Sélectionnez
use Fcntl qw/:flock/        # importer les constantes FLOCK_*
sub mon_verrou {
    flock(MBOX, LOCK_EX)
        or die "Impossible de verrouiller la boîte aux lettres : $!";
        # dans le cas ou quelqu'un ajoutait quelque chose alors que
        #nous étions en train d'attendre et que notre tampon stdio ne
        # soit pas synchronisé
    seek(MBOX, 0, 2)
        or die "Impossible de se positionner à la fin de la boîte aux
                lettres : $!";
}
open(MBOX, "> >/usr/spool/mail/$ENV{'USER'}")
    or die "Impossible d'ouvrir la boîte aux lettres : $!";

mon_verrou();
print MBOX $msg, "\n\n";
close MBOX
    or die "Impossible de fermer la boîte aux lettres : $!";

Sur les systèmes qui supportent un appel système flock(2) réel, les verrous sont hérités à travers les appels à fork. Les autres implémentations ne sont pas aussi chanceuses et sont susceptibles de perdre les verrous à travers les forks. Voir également le module DB_File au chapitre 32 pour d'autres exemples de flock.

fork Image non disponible Image non disponible

 
Sélectionnez
fork

Cette fonction crée deux processus à partir d'un seul en invoquant l'appel système fork(2). En cas de réussite, la fonction renvoie l'ID du nouveau processus fils au processus parent et 0 au processus fils. Si le système ne dispose pas des ressources suffisantes pour allouer un nouveau processus, l'appel échoue et retourne undef. Les descripteurs de fichiers (et parfois les verrous sur ces descripteurs) sont partagés, alors que tout le reste est copié — ou moins paraît l'être.

Dans les versions de Perl antérieures à 5.6, les tampons non vidés le restent dans les deux processus, ce qui veut dire qu'il vous faut parfois positionner $| sur un ou plusieurs handles de fichiers à l'avance pour éviter des sorties dupliquées.

Voici une façon de blinder presque totalement le lancement d'un processus fils tout en testant les erreurs de type « fork impossible » :

 
Sélectionnez
use Errno qw(EAGAIN);
FORK: {
    if ($pid = fork) {
        # on est ici dans le père
        # le pid du processus fils est accessible par $pid
    }
    elsif (defined $pid) { # $pid vaut ici 0 s'il défini
        # on est ici dans le fils
        # le pid du processus père est accessible par getppid
    }
    elsif ($! == EAGAIN) {
        # EAGAIN est l'erreur de fork susceptible d'être corrigée
        sleep 5;
        redo FORK;
    }
    else {
        # erreur de fork étrange
        die "fork impossible :$!\n";
    }
}

Ces précautions ne sont pas nécessaires pour des opérations qui font un fork(2) implicite, comme system, les apostrophes inverses ou l'ouverture d'un processus comme un handle de fichier, car Perl réessaye automatiquement un fork en cas d'échec dans ces cas. Faites très attention à terminer le code du fils par un exit, faute de quoi le fils pourrait quitter par inadvertance le bloc conditionnel et commencer à exécuter du code prévu pour le seul processus père.

Si vous fork ez sans même attendre vos enfants, vous accumulerez les zombies (les processus terminés qui n'ont toujours pas de parents qui les attendent). Sur certains systèmes, vous pouvez éviter ceci en positionnant $SIG{CHLD} à "IGNORE" ; sur la plupart, vous devrez attendre avec wait vos enfants moribonds. Vous en trouverez des exemples dans la description de la fonction wait, ou dans la section Signaux du chapitre 16.

Si un fils fork é hérite des descripteurs fichiers systèmes comme STDIN ou STDOUT qui sont connectés à un pipe distant ou à une socket, il se peut que vous deviez les redirigez vers /dev/null dans le fils. Ceci, car même lorsque le processus père se termine, le fils vivra avec ses copies de ces handles de fichiers. Le serveur distant (mettons comme un script CGI ou une tâche lancée en arrière-plan par un shell distant) semblera bloquer, car il attendra que toutes les copies soient fermées. Rouvrir les handles de fichiers systèmes en les dirigeant vers autre chose corrige ceci.

Sur la plupart des systèmes supportant fork(2), on a porté une attention toute particulière à ce que la fonction soit performante (par exemple, utilisant une technologie de copie en écriture sur les pages de données), ce qui en fait le paradigme dominant de ces dernières décennies pour le multitâche. La fonction fork est susceptible de ne pas être implémentée efficacement, voire de ne pas être implémentée du tout, sur les systèmes qui ne ressemblent pas à Unix. Par exemple, Perl 5.6 émule un fork approprié sur les systèmes de Microsoft, mais sans assurance sur les performances à ce jour. Vous pouvez avoir plus de chances ici avec le module Win32::Process.

format

 
Sélectionnez
format NOM =
    ligne d'image
    liste de valeurs
    ...
.

Cette fonction déclare une séquence nommée de lignes d'images (avec les valeurs associées) à l'usage de la fonction write. Si NOM est omis, le nom par défaut est STDOUT, qui est celui du format par défaut pour le handle de fichier STDOUT. Puisque, comme pour une déclaration de sub, il s'agit d'une déclaration globale au paquetage se produisant à la compilation, toutes les variables utilisées dans la liste de valeurs doivent être visibles au point de la déclaration du format. C'est-à-dire que les variables à portée lexicale doivent être auparavant déclarées dans le fichier, alors que les variables à portée dynamique peuvent n'être initialisées qu'au moment où l'on appelle write. En voici un exemple (qui suppose que nous avons déjà calculé $cout et $quantite :

 
Sélectionnez
my $chn = "widget";             # Une variable de portée lexicale.

format Jolie_Sortie =
Test: @<<<<<<<< @||||| @>>>>>
      $chn,     $%,    '$' . int($num)
.

local $~ = "Jolie_Sortie";      # Sélection du format.
local $num = $cout * $quantite; # Variable de portée dynamique.

write;

Tout comme les handles de fichier, les noms de format sont de simples identificateurs qui existent dans une table de symboles (paquetage) et peuvent être pleinement qualifiés par le nom du paquetage. Dans les typeglobs des entrées d'une table de symboles, les formats résident dans leur propre espace de noms, qui est distinct des handles de fichiers et de répertoires, des scalaires, des tableaux, des hachages ou des sous-programmes. Cependant, comme pour ces six autres types, un format nommé Nimportequoi serait aussi affecté par un local sur le typeglob *Nimportequoi. En d'autres termes, un format n'est qu'un machin de plus, contenu dans un typeglob, indépendant des autres machins.

La section Variables de format du chapitre 7, Formats contient de nombreux détails et des exemples d'utilisation. Le chapitre 28 décrit les variables internes spécifiques aux formats, et les modules English et FileHandle y fournissent un accès aisé.

formline

 
Sélectionnez
formline IMAGE, LISTE

Il s'agit d'une fonction interne utilisée par les format s, bien que vous puissiez également l'appeler vous-même. Elle formate une liste de valeurs d'après le contenu d'IMAGE, en plaçant la sortie dans l'accumulateur de sortie, $^A (ou $ACCUMULATOR si vous utilisez le module English). Finalement, au moment d'un write, le contenu de $^A est écrit vers un handle de fichier, mais vous pouvez aussi bien lire $^A par vous-même pour ensuite le remettre à "". Typiquement, un format lance un formline par ligne de format, mais la fonction formline elle-même ne fait pas attention au nombre de sauts de ligne inclus dans l'IMAGE. Cela veut dire que les tokens ~ et ~~ traitent IMAGE comme une seule ligne. Il peut donc être nécessaire d'employer plusieurs formline s pour implémenter un unique format d'enregistrement, comme le compilateur de format le fait en interne.

Attention si vous mettez des doubles apostrophes autour de l'image, car un caractère @ peut être confondu avec le début d'un nom de tableau. Voir le chapitre 7, Formats, pour des exemples d'utilisation.

getc Image non disponible Image non disponible

 
Sélectionnez
getc HANDLE_FICHIER
getc

Cette fonction renvoie le caractère suivant depuis le fichier d'entrée attaché à HANDLE_FICHIER. Elle renvoie undef à la fin du fichier ou si une erreur d'entrée/sortie se produit. Si HANDLE_FICHIER est omis, la fonction lit depuis STDIN.

Cette fonction est quelque peu lente, mais se révèle parfois utile pour les entrées d'un seul caractère (octet, réellement) au clavier — pourvu que vous vous arrangiez pour que les entrées depuis le clavier ne passent pas par un tampon. Cette fonction demande une entrée non tamponnée depuis la bibliothèque standard d'entrée/sortie. Malheureusement, la bibliothèque standard d'entrée/sortie n'est pas assez standard pour fournir une manière portable de dire au système d'exploitation sous-jacent de donner au système d'entrée/sortie des entrées non tamponnées depuis le clavier. Pour accomplir ceci, vous devez être un peu plus habile et utiliser un style dépendant du système d'exploitation. Sous Unix, vous pourriez dire ceci :

 
Sélectionnez
if ($BSD_STYLE) {
    system "stty cbreak </dev/tty >/dev/tty 2>&1";
} else {
    system "stty", "-icanon", "eol", "\001";
}

$clef = getc;

if ($BSD_STYLE) {
    system "stty -cbreak </dev/tty >/dev/tty 2&1";
} else {
    system "stty", "icanon", "eol", "^@"; # ASCII NUL
}
print "\n";

Ce code met le prochain caractère (octet) frappé sur le terminal dans la chaîne $clef. Si votre programme stty possède des options comme cbreak, vous devrez utiliser le code où $BSD_STYLE est vrai. Sinon, vous devrez utiliser le code où il est faux. Déterminer les options de stty(1) est laissé comme exercice au lecteur.

Le module POSIX en fournit une version plus portable grâce à la fonction POSIX::getattr. Voir aussi le module Term::ReadKey dans votre site CPAN le plus proche pour une approche plus portable et plus flexible.

getgrent Image non disponible

 
Sélectionnez
getgrent
setgrent
endgrent

Ces routines parcourent votre fichier /etc/group (ou peut-être le fichier /etc/group de quelqu'un d'autre, s'il provient d'un serveur quelque part). La valeur renvoyée par getgrent dans un contexte de liste est :

 
Sélectionnez
($nom, $mot_de_passe, $gid, $membres)

$membres contient une liste des noms de login des membres du groupe séparés par des espaces. Pour mettre en œuvre un hachage traduisant les noms de groupes en GID, écrivez ceci :

 
Sélectionnez
while (($nom, $mot_de_passe, $gid) = getgrent) {
    $gid{$nom} = $gid;
}

Dans un contexte scalaire, getgrent renvoie seulement le nom du groupe. Le module standard User::grent supporte une interface orientée par nom pour cette fonction. Voir getgrent(3).

getgrid Image non disponible

 
Sélectionnez
getgrid GID

Cette fonction recherche une entrée de fichier de groupe par le numéro du groupe. La valeur renvoyée dans un contexte de liste est :

 
Sélectionnez
($nom, $mot_de_passe, $gid, $membres)

$membres contient une liste des noms de login des membres du groupe séparés par des espaces. Si vous voulez faire cela de façon répétitive, il vaut mieux utiliser un hachage comme cache en utilisant getgrent.

Dans un contexte scalaire, getgrid renvoie seulement le nom du groupe. Le module standard User::grent supporte une interface orientée par nom pour cette fonction. Voir getgrid(3).

getgrnam Image non disponible

 
Sélectionnez
getgrid NOM

Cette fonction recherche une entrée de fichier de groupe par le nom du groupe. La valeur renvoyée dans un contexte de liste est :

 
Sélectionnez
($nom, $mot_de_passe, $gid, $membres)

$membres contient une liste des noms de login des membres du groupe séparés par des espaces. Si vous voulez faire cela de façon répétitive, il vaut mieux utiliser un hachage comme cache en utilisant getgrent.

Dans un contexte scalaire, getgrnam renvoie seulement le nom du groupe. Le module standard User::grent supporte une interface orientée « par nom » pour cette fonction. Voir getgrnam(3).

gethostbyaddr Image non disponible

 
Sélectionnez
gethostbyaddr ADR, TYPE_ADR

Cette fonction convertit des adresses en noms (et en adresses alternatives). ADR doit être une adresse réseau binaire empaquetée et TYPE_ADR en pratique doit être normalement AF_INET (du module Socket). La valeur de retour dans un contexte de liste est :

 
Sélectionnez
($nom, $alias, $type_adr, $longueur, @adrs) =
    gethostbyaddr($adresse_binaire_empaquetée, $type_adr);

@adrs est une liste d'adresses brutes. Dans le domaine de l'Internet, chaque adresse est (historiquement) longue de 4 octets et peut être découpée en écrivant quelque chose comme ceci :

 
Sélectionnez
($a, $b, $c, $d) = unpack('C4', $adrs[0]);

Ou alors, vous pouvez directement la convertir dans la notation de vecteur pointé avec le modificateur v de sprintf :

 
Sélectionnez
$points = sprintf "%vd", $adrs[0];

La fonction inet_ntoa du module Socket est très utile pour produire une version affichable. Cette approche deviendra importante si et quand nous parviendrons à passer à IPv6.

 
Sélectionnez
use Socket;
$adresse_affichable = inet_ntoa($addrs[0]);

Dans un contexte scalaire, gethostbyaddr renvoie seulement le nom de l'hôte. Pour obtenir une ADR à partir d'un vecteur pointé, écrivez ceci :

 
Sélectionnez
use Socket;
$adr_ip = inet_aton("127.0.0.1");     # localhost
$nom_officiel = gethostbyaddr($adr_ip, AF_INET);

De manière intéressante, vous pouvez avec la version 5.6 de Perl vous passer de inet_aton et employer la nouvelle notation v-chaîne, qui a été inventée pour les numéros de versions, mais il est apparu qu'elle fonctionnait aussi bien pour les adresses IP :

 
Sélectionnez
$adr_ip = v127.0.0.1;

Voir la section Sockets au chapitre 16 pour plus d'exemples. Le module Net::hostent supporte une interface orientée « par nom » pour cette fonction. Voir gethostbyaddr(3).

gethostbyname Image non disponible

 
Sélectionnez
gethostbyname NOM

Cette fonction convertit un nom d'hôte réseau en son adresse correspondante (et en d'autres noms). La valeur de retour dans un contexte de liste est :

 
Sélectionnez
($nom, $alias, $type_adr, $longueur, @adrs) =
    gethostbyname($nom_hote_distant);

@adrs est une liste d'adresses brutes. Dans le domaine de l'Internet, chaque adresse est (historiquement) longue de 4 octets et peut être découpée en écrivant quelque chose comme ceci :

 
Sélectionnez
($a, $b, $c, $d) = unpack('C4', $adrs[0]);

Vous pouvez directement la convertir dans la notation de vecteur avec le modificateur v de sprintf :

 
Sélectionnez
$points = sprintf "%vd", $adrs[0];

Dans un contexte scalaire, gethostbyname renvoie uniquement l'adresse de l'hôte :

 
Sélectionnez
use Socket;
$adr_ip = gethostbyname($hote_distant);
printf "%s a comme adresse %s\n",
    $hote_distant, inet_ntoa($adr_ip);

Voir la section Sockets au chapitre 16 pour une autre approche. Le module Net::hostent supporte une interface orientée par nom pour cette fonction. Voir également gethostbyname(3).

gethostent Image non disponible

 
Sélectionnez
gethostent
sethostent RESTE_OUVERT
endhostent

Ces fonctions parcourent votre fichier /etc/hosts et renvoient chaque entrée une par une. La valeur de retour de gethostent dans un contexte de liste est :

 
Sélectionnez
($nom, $alias, $longueur, @adrs)

@adrs est une liste d'adresses brutes. Dans le domaine Internet, chaque adresse est longue de 4 octets et peut être découpée en écrivant quelque chose comme ceci :

 
Sélectionnez
($a, $b, $c, $d) = unpack('C4', $adrs[0]);

Les scripts qui utilisent gethostent ne doivent pas être considérés comme portables. Si une machine utilise un serveur de noms, elle interrogera la quasi-totalité de l'Internet pour tenter de satisfaire une requête portant sur toutes les adresses de toutes les machines de la planète. Voir gethostent(3) pour d'autres détails.

Le module Net::hostent supporte une interface orientée par nom pour cette fonction.

getlogin Image non disponible

 
Sélectionnez
getlogin

Cette fonction renvoie le nom de login courant s'il est trouvé. Sur les systèmes Unix, il est lu à partir du fichier utmp(5). Si la fonction renvoie faux, utilisez getpwuid à la place. Par exemple :

 
Sélectionnez
$login = getlogin() || (getpwuid($<))[0]) || "Intrus !!";

getnetbyaddr Image non disponible

 
Sélectionnez
getnetbyaddr ADR, TYPE_ADR

Cette fonction convertit une adresse réseau vers le nom ou les noms de réseau correspondants. La valeur renvoyée dans un contexte de liste est :

 
Sélectionnez
use Socket;
($nom, $alias, $type_adr, $reseau) = getnetbyaddr(127, AF_INET);

Dans un contexte scalaire, getnetbyaddr renvoie seulement le nom du réseau. Le module Net::netent supporte une interface orientée par nom pour cette fonction. Voir getnetbyaddr(3).

getnetbyname Image non disponible

 
Sélectionnez
getnetbyname NOM

Cette fonction convertit un nom de réseau vers son adresse réseau correspondante. La valeur de retour dans un contexte de liste est :

 
Sélectionnez
($nom, $alias, $type_adr, $reseau) = getnetbyname("loopback");

Dans un contexte scalaire, getnetbyname renvoie seulement l'adresse du réseau. Le module Net::netent supporte une interface orientée par nom pour cette fonction. Voir getnetbyname(3).

getnetent Image non disponible

 
Sélectionnez
getnetent
setnetent RESTE_OUVERT
endnetent

Ces fonctions parcourent votre fichier /etc/networks. La valeur renvoyée dans un contexte de liste est :

 
Sélectionnez
($nom, $alias, $type_adr, $reseau) = getnetent();

Dans un contexte scalaire, getnetent renvoie seulement le nom du réseau. Le module Net::netent supporte une interface orientée par nom pour cette fonction. Voir getnetent(3).

Le concept de nom de réseau semble un peu désuet de nos jours ; la plupart des adresses IP étant sur des sous-réseaux innommés (et innommables).

getpeername Image non disponible Image non disponible Image non disponible

 
Sélectionnez
getpeername SOCKET

Cette fonction l'adresse socket empaquetée de l'autre extrémité de la connexion SOCKET. Par exemple :

 
Sélectionnez
use Socket;
$son_adr_sock     = getpeername SOCK;
($port, $son_adr) = sockaddr_in($son_adr_sock);
$son_nom_hote     = gethostbyaddr($son_adr, AF_INET);
$son_adr_chaine   = inet_ntoa($son_adr);

getpgrp Image non disponible

 
Sélectionnez
getpgrp PID

Cette fonction renvoie l'identifiant du groupe de processus courant pour le PID spécifié (employez un PID égal à 0 pour le processus courant). L'invocation de getpgrp lèvera une exception sur une machine n'implémentant pas getpgrp(2). Si PID est omis, la fonction renvoie le groupe de processus du processus courant (ce qui est identique à un PID de 0). Sur les systèmes qui implémentent cet opérateur avec l'appel système POSIX getpgrp(2), PID doit être omis ou, s'il est fourni, doit être égal à 0.

getppid Image non disponible

 
Sélectionnez
getppid

Cette fonction renvoie l'identifiant du processus parent. Sur un système UNIX typique, si l'ID du processus père se change en 1, c'est que ce dernier est mort et que le processus courant a été adopté par le programme init(8).

getpriority Image non disponible Image non disponible

 
Sélectionnez
getpriority QUOI, QUI

Cette fonction renvoie la priorité courante d'un processus, d'un groupe de processus ou d'un utilisateur. Voir getpriority(2). Son invocation lèvera une exception sur une machine où getpriority(2) n'est pas implémentée.

Le module BSD::Resource de CPAN fournit une interface plus pratique, comprenant les constantes symboliques PRIO_PROCESS, PRIO_PGRP et PRIO_USER qu'il faut fournir pour l'argument QUOI. Bien qu'elles soient généralement égales à 0, 1 et 2 respectivement, vous ne savez vraiment pas ce qui peut se passer aux sombres confins des fichiers #include du C.

Une valeur de 0 pour QUI signifie le processus, le groupe de processus ou l'utilisateur courant, ainsi pour obtenir la priorité du processus en cours, utilisez :

 
Sélectionnez
$prio_cour = getpriority(0, 0);

getprotobyname Image non disponible

 
Sélectionnez
getprotobyname NOM

Cette fonction convertit un nom de protocole vers son numéro correspondant. La valeur renvoyée dans un contexte de liste est :

 
Sélectionnez
($nom, $alias, $numero_protocole) = getprotobyname("tcp");

Lorsqu'on l'appelle dans un contexte scalaire, getprotobyname renvoie seulement le numéro de protocole. Le module Net::proto supporte une interface orientée par nom pour cette fonction. Voir getprotobyname(3).

getprotobynumber Image non disponible

 
Sélectionnez
getprotobynumber NUMERO

Cette fonction convertit un numéro de protocole vers son nom correspondant. La valeur renvoyée dans un contexte de liste est :

 
Sélectionnez
($nom, $alias, $numero_protocole) = getprotobynumber(6);

Lorsqu'on l'appelle dans un contexte scalaire, getprotobynumber renvoie seulement le nom de protocole. Le module Net::proto supporte une interface orientée par nom pour cette fonction. Voir getprotobynumber(3).

getprotoent Image non disponible

 
Sélectionnez
getprotoent
setprotoent RESTE_OUVERT
endprotoent

Ces fonctions parcourent votre fichier /etc/protocols. Dans un contexte de liste, la valeur renvoyée par getprotoent est :

 
Sélectionnez
($nom, $alias, $numero_protocole) = getprotoent();

Lorsqu'on l'appelle dans un contexte scalaire, getprotoent renvoie seulement le numéro du protocole. Le module Net::protoent supporte une interface orientée par nom pour cette fonction. Voir getprotent(3).

getpwent Image non disponible Image non disponible

 
Sélectionnez
getpwent
setpwent
endpwent

Ces fonctions parcourent conceptuellement votre fichier /etc/passwd, bien que ceci puisse impliquer le fichier /etc/shadow si vous êtes le super-utilisateur et que vous utilisez les mots de passe « shadow », NIS (ex-Pages Jaunes, Yellow Pages, YP) ou NIS+. La valeur renvoyée dans un contexte de liste est :

 
Sélectionnez
($nom,$mot_de_passe,$uid,$gid,$quota,$commentaire,$nom_reel,$rep,$shell)= getpwent();

Certaines machines peuvent utiliser les champs quota et commentaire à d'autres fins que leurs noms ne le laissent supposer, mais les champs restants seront toujours les mêmes. Pour mettre en œuvre un hachage de traduction des noms de login en UID, écrivez ceci :

 
Sélectionnez
while (($nom, $mot_de_passe, $uid) = getpwent()) {
    $uid{$nom} = $uid;
}

Dans un contexte scalaire, getpwent renvoie seulement le nom d'utilisateur. Le module User::pwent supporte une interface orientée par nom pour cette fonction. Voir getpwent(3).

getpwnam Image non disponible Image non disponible

 
Sélectionnez
getpwnam NOM

Cette fonction convertit un nom d'utilisateur vers l'entrée correspondante du fichier /etc/passwd. La valeur renvoyée dans un contexte de liste :

 
Sélectionnez
($nom,$mot_de_passe,$uid,$gid,$quota,$commentaire,$nom_reel,$rep,$shell)= getpwnam("daemon");

Sur les systèmes qui supportent les mots de passe « shadow », vous devrez être le super-utilisateur pour récupérer le véritable mot de passe. Votre bibliothèque C doit remarquer que vous avez les permissions suffisantes et ouvre votre fichier /etc/shadow (ou n'importe quel endroit où le fichier shadow est conservé). Du moins, c'est censé fonctionner ainsi. Perl essayera de faire ceci si votre bibliothèque C est trop stupide pour le remarquer.

Pour faire des recherches répétitives, mieux vaut utiliser un hachage comme cache avec getpwent.

Dans un contexte scalaire, getpwnam renvoie seulement l'UID numérique. Le module User::pwent supporte une interface orientée par nom pour cette fonction. Voir getpwnam(3) et passwd(5).

getpwuid Image non disponible Image non disponible

 
Sélectionnez
getpwuid UID

Cette fonction convertit un UID numérique vers l'entrée correspondante du fichier /etc/passwd. La valeur renvoyée dans un contexte de liste :

 
Sélectionnez
($nom,$mot_de_passe,$uid,$gid,$quota,$commentaire,$nom_reel,$rep,$shell)= getpwuid(2);

Pour faire des recherches répétitives, mieux vaut utiliser un hachage comme cache avec getpwent.

Dans un contexte scalaire, getpwuid renvoie seulement le nom de l'utilisateur. Le module User::pwent supporte une interface orientée « par nom » pour cette fonction. Voir getpwnam(3) et passwd(5).

getservbyname Image non disponible

 
Sélectionnez
getservbyname NOM, PROTO

Cette fonction convertit un nom de service (port) vers son numéro de port correspondant. PROTO est un nom de protocole comme "tcp". La valeur renvoyée dans un contexte de liste est :

 
Sélectionnez
($nom, $alias, $numero_port, $nom_protocole) = getservbyname("www", "tcp");

Dans un contexte scalaire, getservbyname renvoie seulement le numéro du port de service. Le module Net::servent supporte une interface orientée par nom pour cette fonction. Voir getservbyname(3).

getservbyport Image non disponible

 
Sélectionnez
getservbyport PORT, PROTO

Cette fonction convertit un numéro de service (port) vers les noms correspondants. PROTO est un nom de protocole comme "tcp". La valeur renvoyée dans un contexte de liste est :

 
Sélectionnez
($nom, $alias, $numero_port, $nom_protocole) = getservbyport(80, "tcp");

Dans un contexte scalaire, getservbyport renvoie seulement le nom du service. Le module Net::servent supporte une interface orientée par nom pour cette fonction. Voir getservbyport(3).

getservent Image non disponible

 
Sélectionnez
getservent
setservent RESTE_OUVERT
endservent

Cette fonction parcourt votre fichier /etc/services ou son équivalent. La valeur renvoyée dans un contexte de liste est :

 
Sélectionnez
($nom, $alias, $numero_port, $nom_protocole) = getservent();

Dans un contexte scalaire, getservent renvoie seulement le nom du port de service. Le module Net::servent supporte une interface orientée par nom pour cette fonction. Voir getservent(3).

getsockname Image non disponible Image non disponible Image non disponible

 
Sélectionnez
getsockname SOCKET

Cette fonction renvoie l'adresse socket empaquetée de cette extrémité de la connexion SOCKET. (Et pourquoi ne connaîtriez-vous plus votre propre adresse ? Peut-être parce que vous avez attaché une adresse contenant des jokers (wildcards) à la socket serveur avant de faire un accept et que maintenant vous avez besoin de savoir à travers quelle interface quelqu'un est connecté avec vous. Ou la socket vous a été passée par votre processus père — inetd, par exemple.)

 
Sélectionnez
use Socket;
$mon_adr_sock = getsockname SOCK;
($port, $mon_adr) = sockaddr_in($mon_adr_sock);
$mon_nom = gethostbyaddr($mon_adr, AF_INET);
printf "Je suis %s [%vd]\n", $mon_nom, $mon_adr;

getsockopt Image non disponible Image non disponible Image non disponible

 
Sélectionnez
getsockopt SOCKET, NIVEAU, NOM_OPTION

Cette fonction renvoie l'option de socket requise ou undef en cas d'erreur. Voir setsockopt pour plus d'informations.

glob Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
glob EXPR
glob

Cette fonction renvoie la valeur de EXPR avec expansion des noms de fichiers, exactement comme un shell le ferait. Il s'agit de la fonction interne implémentant l'opérateur <*>.

Pour des raisons historiques, l'algorithme correspond au style d'expansion de csh(1) et pas à celui du Bourne Shell. Les versions de Perl antérieures à 5.6 utilisaient un processus externe, mais la 5.6 et les suivantes exécutent les globs en interne. Les fichiers dont le premier caractère est un point (« . ») sont ignorés sauf si ce caractère correspond explicitement. Un astérisque (« * ») correspond à n'importe quelle séquence de n'importe quels caractères (y compris aucun). Un point d'interrogation (« ? ») correspond à un unique caractère, quel qu'il soit. Une séquence entre crochets (« [...] ») spécifie une simple classe de caractères, comme « [chy0-9] ». Les classes de caractères peuvent être niées avec un accent circonflexe, comme dans « *.[^oa] », qui correspond à tous les fichiers ne commençant pas par un point et dont les noms contiennent un point suivi par un seul caractère qui ne soit ni un « a », ni un « o » à la fin du nom. Un tilde (« ~ ») se développe en un répertoire maison, comme dans « ~/.*rc » pour les fichiers « rc » de l'utilisateur courant, ou « ~caro/Mail/* » pour tous les fichiers mails de Caro. On peut employer des accolades pour les alternatives, comme dans « ~/.{mail,ex,csh,twm,}rc » pour obtenir ces fichiers rc particuliers.

Si vous voulez glober sur des noms de fichiers qui peuvent contenir des espaces, vous devrez utilisez le module File::Glob directement, puisque les grands-pères de glob utilisaient les espaces pour séparer plusieurs motifs comme <*.c *.h>. Pour plus de détail, voir File::Glob au chapitre 32. L'appel de glob (ou de l'opérateur <*>) fait automatiquement un use sur ce module, donc si se module s'évapore mystérieusement de votre bibliothèque, une exception est levée.

Lorsque vous appelez open, Perl ne développe pas les jokers, y compris les tildes. Vous devez d'abord glober les résultats.

 
Sélectionnez
open(MAILRC, "~/.mailrc")            # FAUX : le tilde est un truc du shell
    or die "Impossible d'ouvrir ~/.mailrc : $!";
open(MAILRC, (glob("~/.mailrc"))[0]) # développe d'abord le tilde
    or die "Impossible d'ouvrir ~/.mailrc : $!";

La fonction glob n'a aucun rapport avec la notion Perl de typeglobs, sinon qu'elles utilisent toutes deux un * pour représenter plusieurs éléments.

Voir aussi la section Opérateur de globalisation des noms de fichier au chapitre 2.

gmtime

 
Sélectionnez
gmtime EXPR
gmtime

Cette fonction convertit une heure renvoyée par la fonction time en un tableau de neuf éléments dont l'heure est en phase avec le méridien de Greenwich (alias GMT ou UTC, ou même Zoulou dans certaines cultures, dont ne fait bizarrement pas partie la culture Zoulou). Elle est généralement employée comme suit :

 
Sélectionnez
#  0    1     2      3     4      5      6      7       8
($sec,$min,$heure,$mjour,$mois,$annee,$sjour,$ajour,$est_dst) = gmtime();

Si, comme dans ce cas, EXPR est omise, la fonction effectue gmtime(time()). Le module Time::Local de la bibliothèque Perl contient un sous-programme, timegm, qui peut à l'inverse convertir la liste vers une valeur de time.

Tous les éléments sont numériques et proviennent directement d'une struct tm (une structure de programmation C ; pas d'affolement). Cela signifie en particulier que $mois se situe dans l'intervalle 0..11 avec janvier comme le mois 0 et que $sjour est dans 0..6 avec dimanche comme jour 0. Vous pouvez vous rappeler de ceux qui commencent par zéro, car ce sont ceux que vous utilisez toujours comme indices dans les tableaux débutant par zéro contenant les noms des mois et des jours.

Par exemple, pour afficher le mois courant à Londres, vous pouvez écrire :

 
Sélectionnez
$mois_londres = (qw((Jan Fev Mar Avr Mai Jun
                     Jui Aou Sep Oct Nov Dec))[(gmtime)[4]];

$annee est le nombre d'années depuis 1900 ; c'est-à-dire qu'en 2023, $annee vaudra 123, et pas simplement 23. Pour obtenir l'année sur 4 chiffres, il suffit d'écrire $annee+1900. Pour l'avoir sur 2 chiffres (par exemple « 01 » en 2001), utilisez sprintf("%02d", $annee % 100).

Dans un contexte scalaire, gmtime renvoie une chaîne ressemblant à ctime(3) basée sur la valeur de l'heure GMT. Le module Time::gmtime supporte une interface orientée « par nom » pour cette fonction. Voir aussi POSIX::strftime pour une approche permettant de formater des dates avec une granularité plus fine.

Cette valeur scalaire n'est pas dépendante des « locales », mais plutôt interne à Perl. Voir aussi le module Time::Local et les fonctions strftime(3) et mktime(3) disponibles via le module POSIX. Pour obtenir des chaînes pour la date qui soient similaires, mais locales, positionnez vos variables d'environnement locales de manière appropriée (merci de voir la page de man pour perllocale) et essayez :

 
Sélectionnez
use POSIX qw(strftime);
$chaine_maintenant = strftime "%a %b %e %H:%M:%S %Y", gmtime;

Les caractères d'échappement %a et %b, qui représentent la forme abrégée pour le jour de la semaine et le mois de l'année, peuvent ne pas être nécessairement de trois caractères dans toutes les « locales ».

goto Image non disponible

 
Sélectionnez
goto ETIQUETTE
goto EXPR
goto &NOM

goto ETIQUETTE trouve l'instruction étiquetée par ETIQUETTE et continue l'exécution à partir de là. Si l'ETIQUETTE est impossible à trouver, une exception est levée. Elle ne peut pas être utilisée pour aller dans une construction demandant une initialisation, comme un sous-programme ou une boucle foreach. De même, elle ne peut être employée pour rentrer dans une construction optimisée. Elle peut être utilisée pour aller quasiment partout ailleurs dans l'espace de portée d'adressage dynamique,(201) y compris pour sortir des sous-programmes, mais il vaut alors mieux employer une autre instruction comme last ou die. L'auteur de Perl n'a jamais ressenti le besoin d'utiliser cette forme de goto (en Perl — en C, c'est une autre histoire).

Pour aller plus loin dans l'orthogonalité (et plus profond dans la stupidité), Perl autorise gotoEXPR qui s'attend à ce que EXPR donne un nom d'étiquette, dont l'emplacement ne peut jamais être résolu avant l'exécution puisque l'étiquette est inconnue lorsqu'on compile l'instruction. Cela permet des goto s calculés comme en FORTRAN, mais ce n'est pas vraiment recommandé(202) lorsqu'on cherche à optimiser la maintenabilité :

 
Sélectionnez
goto +("TRUC", "MACHIN", "CHOUETTE")[$i];

Sans aucun rapport, le goto &NOM fait de la grande magie en substituant un appel au sous-programme nommé en lieu et place du sous-programme actuellement en cours. Cette construction est utilisée sans scrupule par les sous-programmes AUTOLOAD qui veulent en charger un autre pour ensuite prétendre que celui-ci — et non l'original — a été appelé en premier lieu (sauf que toute modification de @_ dans le sous-programme d'origine est propagée dans le sous-programme de remplacement). Après le goto, même caller ne pourra pas dire que la routine AUTOLOAD originelle avait été appelée en premier lieu.

grep

 
Sélectionnez
grep EXPR, LISTE
grep BLOC LISTE

Cette fonction évalue EXPR ou BLOC dans un contexte booléen pour chaque élément de LISTE, en positionnant temporairement $_ avec chaque élément tout à tour, un peu comme la construction foreach. Dans un contexte de liste, elle renvoie la liste des éléments pour lesquels l'expression est vraie. (L'opérateur a été nommé d'après le bien-aimé programme UNIX qui extrait les lignes d'un fichier qui correspondent à un motif particulier. En Perl, l'expression est souvent un motif, mais ce n'est pas obligatoire.) Dans un contexte scalaire, grep renvoie le nombre d'occurrences où l'expression est vraie.

À supposer que @toutes_les_lignes contienne des lignes de code, cet exemple élimine les lignes de commentaires :

 
Sélectionnez
@lignes_de_code = grep !/^\s*#/, @toutes_les_lignes;

$_ étant un alias implicite à chaque valeur de la liste, l'altération de $_ modifiera les éléments de la liste originelle. Bien que ceci soit utile et supporté, les résultats peuvent devenir bizarres si l'on ne s'y attend pas. Par exemple,

 
Sélectionnez
@liste = qw(barney fred dino wilma);
@liste_grep = grep { s/^[bfd]// } @liste;

@liste_grep contient maintenant « arney », « red », « ino », mais @liste est devenu « arney », « red », « ino », « wilma » ! Danger de bourde de programmeur.

Voir également map. Les deux instructions suivantes sont fonctionnellement équivalentes :

 
Sélectionnez
@sortie = grep { EXPR } @entree;
@sortie = map { EXPR ? $_ : () } @entree

hex Image non disponible

 
Sélectionnez
hex EXPR
hex

Cette fonction interprète EXPR comme une chaîne hexadécimale et renvoie la valeur décimale équivalente. S'il y un « 0x » au début, il est ignoré. Pour interpréter des chaînes commençant soit par 0, soit par 0b, ou par 0x, voir oct. Le code suivant met $nombre à 4 294 906 560 :

 
Sélectionnez
$nombre = hex("ffff12c0");

Pour la fonction inverse, employez sprintf :

 
Sélectionnez
sprintf "%lx", $nombre;  # (la lettre L en minuscule, pas le chiffre un.)

Les chaînes hexadécimales ne peuvent représenter que des entiers. Les chaînes qui causeraient un débordement de la limite pour les entiers déclenchent un avertissement.

import

 
Sélectionnez
import NOM_CLASSE LISTE
import NOM_CLASSE

Il n'existe pas de fonction import intégrée. Il s'agit essentiellement d'une méthode de classe ordinaire définie (ou héritée) par les modules qui désirent exporter des noms vers un autre module par l'intermédiaire de l'opérateur use. Voir use pour plus de détails.

index

 
Sélectionnez
index CHAINE, SOUS_CHAINE, DECALAGE
index CHAINE, SOUS_CHAINE

Cette fonction recherche une chaîne à l'intérieur d'une autre. Elle renvoie la position de la première occurrence de SOUS_CHAINE dans CHAINE. Le DECALAGE, s'il est spécifié, indique à partir de combien de caractère débute la recherche. Les positions partent de 0 (ou de là où vous avez positionné la variable de base des indices $[, mais ne faites pas ça). Si la sous-chaîne n'est pas trouvée, la fonction renvoie un de moins que la base, généralement -1. Pour balayer une chaîne, on peut écrire :

 
Sélectionnez
$pos = -1;
while (($pos = index($chaine, $chaine_recherchee, $pos)) > -1) {
    print "Trouvé en $pos\n";
    $pos++;
}

int Image non disponible

 
Sélectionnez
int EXPR
int

Cette fonction renvoie la partie entière de EXPR. Si vous êtes un programmeur C, vous êtes susceptible d'oublier fréquemment d'utiliser int en conjonction avec la division, qui est une opération en virgule flottante en Perl :

 
Sélectionnez
$age_moyen = 939/16;      # donne 58.6875 (58 en C)
$age_moyen = int 939/16;  # donne 58

Vous ne devez pas employer cette fonction pour arrondir dans tous les cas, car elle tronque vers 0 et parce que la représentation pour la machine des nombres en virgule flottante peut quelquefois produire des résultats qui ne sont pas intuitifs. Par exemple, int(-6.725/0.025) donnera -268 au lieu de la valeur correcte -269 ; ceci, car la valeur est plus proche de -268.99999999999994315658. Généralement, les fonctions sprintf, printf ou POSIX::floor ou encore POSIX::ceil vous serviront plus que ne le ferait int.

 
Sélectionnez
$n = sprintf("%.0f", $f);   # arrondit (et ne tronque pas)
                            # vers l'entier le plus proche

Ioctl Image non disponible Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
ioctl HANDLE_FICHIER, FONCTION, SCALAIRE

Cette fonction implémente l'appel système ioctl(2) qui contrôle les entrées/sorties. Il vous faudra peut-être d'abord écrire pour obtenir les définitions de fonctions correctes :

 
Sélectionnez
require "sys/ioctl.ph";    # probablement /usr/local/lib/perl/sys/ioctl.ph

Si sys/ioctl.ph n'existe pas ou ne comporte pas les définitions correctes, vous devrez écrire les vôtres, en vous basant sur vos en-têtes de fichiers C comme sys/ioctl.h. (La distribution Perl contient un script appelé h2ph pour vous y aider, mais cela reste complexe.) SCALAIRE sera lu ou écrit (ou les deux) selon la FONCTION — un pointeur sur la valeur chaîne de SCALAIRE sera passé comme troisième argument de l'appel réel à ioctl(2). (Si SCALAIRE n'a pas de valeur chaîne, mais une valeur numérique, c'est cette dernière qui sera passée directement au lieu d'un pointeur sur la valeur chaîne.) Les fonctions pack et unpack servent notamment à manipuler les valeurs des structures utilisées par ioctl. L'exemple suivant détermine combien d'octets sont disponibles pour être lus en utilisant un FIONREAD :

 
Sélectionnez
require 'sys/ioctl.ph';

$taille = pack("L", 0);
ioctl(HF, FIONREAD(), $taille)
    or die "Impossible d'appeler ioctl : $!\n";
$taille = unpack("L", $taille);

Si h2ph n'a pas été installé ou ne fonctionne pas dans votre cas, vous pouvez faire un grep à la main sur les fichiers d'en-têtes ou écrire un petit programme C pour afficher la valeur.

La valeur de retour d'ioctl (et de fcntl) est comme suit :

L'appel système renvoie

Perl renvoie

-1

undef.

0

La chaîne « 0 but true ».

autre chose

Le même nombre.

Perl renvoie donc vrai pour un succès et faux pour un échec, tout en vous laissant facilement déterminer la valeur renvoyée par le système d'exploitation :

 
Sélectionnez
$val_ret = ioctl(...) || -1;
printf "ioctl a en fait renvoyé %d\n", $val_ret;

La chaîne spéciale « 0 but true » (N.d.T. : 0, mais vrai) est exempte des avertissements de -w à propos des conversions numériques inadaptées.

Les appels à ioctl ne doivent pas être considérés comme portables. Si, par exemple, vous voulez simplement désactiver l'écho une seule fois pour le script tout entier, il est beaucoup plus portable d'écrire :

 
Sélectionnez
system "stty -echo"; # Fonctionne sur la plupart des Unix

Ce n'est pas parce qu'il est possible de faire quelque chose en Perl qu'il faut le faire. Pour citer l'apôtre Saint Paul : « Tout est acceptable — mais tout n'est pas bénéfique. »

Pour une meilleure portabilité, vous devriez regarder le module de CPAN Term::Read-Key.

join

 
Sélectionnez
join EXPR, LISTE

Cette fonction joint les chaînes séparées de LISTE en une chaîne unique dont les champs sont séparés par la valeur de EXPR, et renvoie la chaîne résultante. Par exemple :

 
Sélectionnez
$enreg = join ':', $login,$mot_de_passe,$uid,$gid,$nom_reel,$rep,$shell;

Pour faire l'inverse, voir split. Pour joindre des éléments dans des champs à position fixe, voir pack. La manière la plus efficace de concaténer des chaînes consiste à les joindre avec la chaîne vide :

 
Sélectionnez
$chaine = join "", @tableau;

Au contraire de split, join ne prend pas un motif comme premier argument, et elle produit un avertissement si vous tentez de le faire.

keys

 
Sélectionnez
keys HACHAGE

Cette fonction renvoie une liste constituée de toutes les clefs du HACHAGE indiqué. Les clefs sont renvoyées dans un ordre apparemment aléatoire, mais c'est le même que celui produit par les fonctions values ou each (à supposer que le hachage n'a pas été modifié entre les appels). Comme effet de bord, elle réinitialise l'itérateur de HACHAGE. Voici une manière (un peu tordue) d'afficher votre environnement :

 
Sélectionnez
@clefs = keys %ENV;         # les clefs sont dans le même ordre que
@valeurs = values %ENV;     # les valeurs, comme ceci le démontre
while (@clefs) {
    print pop(@clefs), '=', pop(@valeurs), "\n";
}

Vous préférez peut-être plus voir votre environnement affiché dans l'ordre des clefs :

 
Sélectionnez
foreach $clef (sort keys %ENV) {
    print $clef, '=', $ENV{$clef}, "\n";
}

Vous pouvez trier les valeurs d'un hachage directement, mais c'est plutôt inutile en l'absence d'une solution pour retrouver les clefs à partir des valeurs. Pour trier un hachage par ses valeurs, vous avez généralement besoin de trier le résultat de keys en fournissant une fonction de comparaison qui accède aux valeurs en fonction des clefs. Voici un tri numérique décroissant d'un hachage par ses valeurs :

 
Sélectionnez
foreach $clef (sort { $hachage{$b} <=> $hachage{$a} } keys %hachage) {
    printf "%4d %s\n", $hachage{$clef}, $clef;
}

L'utilisation de keys sur un hachage lié à un gros fichier DBM produirait une liste volumineuse, et donc un processus volumineux. Il vaut mieux que vous utilisiez dans ce cas la fonction each, qui parcourt les entrées du hachage une à une sans les absorber toutes dans une seule liste gargantuesque.

Dans un contexte scalaire, keys renvoie le nombre d'éléments du hachage (et réinitialise l'itérateur de each). Cependant, pour obtenir cette information à partir d'un hachage lié, y compris à un fichier DBM, Perl doit le parcourir en entier, ce qui n'est pas très efficace dans ce cas. L'appel de keys dans un contexte vide facilite ceci.

Utilisée en tant que lvalue, keys augmente le nombre de cellules de hachage (N.d.T. : hash buckets) allouées pour le hachage donné. (C'est la même chose que d'étendre a priori un tableau en assignant un nombre élevé pour $#tableau.) Étendre a priori un hachage peut se traduire par un gain de performance, s'il vous arrive de savoir si le hachage va être gros, et quelle grosseur il atteindra. Si vous écrivez :

 
Sélectionnez
keys %hachage = 1000;

le %hachage aura alors au moins 1000 cellules allouées pour lui (vous aurez en fait 1024 cellules, puisqu'on arrondit à la prochaine puissance de deux). Vous pouvez diminuer le nombre de cellules allouées pour un hachage en utilisant keys de cette manière (mais vous n'aurez pas à vous inquiéter de faire cela par accident, puisqu'essayer est sans effet). Les cellules seront conservées même si vous faites %hachage = (). Utilisez undef %hachage si vous voulez libérer de la place en mémoire alors que %hachage est toujours dans la portée courante.

Voir également each, value et sort.

kill Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
kill SIGNAL, LISTE

Cette fonction envoie un signal à une liste de processus. Pour le SIGNAL, vous pouvez utiliser soit un entier, soit le nom d'un signal entre apostrophes (sans le « SIG » au début). Une tentative d'employer un SIGNAL non reconnu lève une exception. La fonction renvoie le nombre de processus qui ont réussi à recevoir le signal. Si SIGNAL est négatif, la fonction touchera des groupes de processus au lieu des processus. (Sur System V, un numéro de processus négatif touchera également des groupes de processus, mais ce n'est pas portable.) Un PID égal à zéro enverra le signal à tous les processus du même groupe que celui de l'émetteur. Par exemple :

 
Sélectionnez
$compt = kill 1, $fils1, $fils2;
kill 9, @mourants;
kill 'STOP', getppid        # Peut suspendre *ainsi* le shell de login
    unless getppid == -1;   # (Mais ne titillez pas init(8).)

Un SIGNAL valant 0 teste si un processus est toujours en vie et que vous avez toujours les permissions pour lui envoyer un signal. Aucun signal n'est envoyé. Vous pouvez de cette manière détecter si un processus est toujours en vie et s'il n'a pas changé d'UID.

 
Sélectionnez
use Errno qw(ESRCH EPERM);

if (kill 0 => $larbin) {
    print "$larbin est en vie !\n";
} elsif ($! == EPERM) {                 # UID changé
    print "$larbin a échappé à mon contrôle !\n";
} elsif ($! == ESRCH) {                 # ou zombie
    print "$larbin est décédé.\n";
} else {
    warn "Bizarre : je n'ai pas pu vérifier l'état de $larbin : $!\n";
}

Voir la section Signaux au chapitre 16.

last Image non disponible

 
Sélectionnez
last ETIQUETTE
last

L'opérateur last sort immédiatement de la boucle en question, exactement comme l'instruction break en C ou en Java (lorsqu'elle est utilisée dans les boucles). Si l'ETIQUETTE est omise, l'opérateur se réfère à la boucle la plus intérieure qui l'encadre. Le bloc continue, s'il existe, n'est pas exécuté.

 
Sélectionnez
LIGNE: while (<MSG_MAIL>) {
    last LIGNE if /^$/; # sort lorsqu'on en a fini avec les en-têtes
    # suite de la boucle ici
}

last ne peut pas être employé pour sortir d'un bloc qui renvoie une valeur, comme eval {}, sub {} ou do {}, et ne doit pas être utilisé pour sortir d'une opération grep ou map. Si les avertissements sont actifs, Perl vous préviendra si vous faites un last pour sortir d'une boucle qui est hors de votre portée lexicale, comme une boucle dans une sous-routine appelante.

Un bloc en soi-même est sémantiquement identique à une boucle qui ne s'exécute qu'une seule fois. Ainsi last peut être employé pour effectuer une sortie anticipée d'un tel bloc.

Voir aussi le chapitre 4 pour des illustrations du fonctionnement de last, next, redo et continue.

lc Image non disponible Image non disponible

 
Sélectionnez
lc EXPR
lc

Cette fonction renvoie une version en minuscules de EXPR. Il s'agit de la fonction interne implémentant l'échappement \L dans les chaînes entre guillemets. La valeur de votre locale LC_CTYPE est respectée si use locale est actif, bien que la manière dont les locales interagissent avec Unicode est toujours un sujet à l'étude, comme ils disent. Voir la page de man perllocale pour les résultats les plus à jour.

lcfirst Image non disponible Image non disponible

 
Sélectionnez
lcfirst EXPR
lcfirst

Cette fonction renvoie une version de EXPR avec le premier caractère en minuscule. Il s'agit de la fonction interne implémentant l'échappement \l dans les chaînes entre guillemets. La valeur de votre locale LC_CTYPE est respectée si vous employez use locale et nous tâchons de comprendre le rapport avec Unicode.

length Image non disponible

 
Sélectionnez
length EXPR
length

Cette fonction renvoie la longueur en caractères de la valeur scalaire de EXPR. Si EXPR est omise, la fonction renvoie la longueur de $_ (mais prenez garde que ce qui suit ne ressemble pas au début d'une EXPRression, faute de quoi le moteur lexical de Perl sera perturbé. Par exemple, length < 10 ne compilera pas. En cas de doute, mettez des parenthèses.)

N'essayez pas d'utiliser length pour trouver la taille d'un tableau ou d'un liste. scalar @tableau donne la taille d'un tableau et scalar keys %hachage celle des couples clef/valeur d'un hachage. (Le scalar est habituellement omis lorsqu'il est redondant.)

Pour trouver la taille d'une chaîne en octets plutôt qu'en caractères, écrivez :

 
Sélectionnez
$oct_long = do { use bytes; length $chaine; };

ou

 
Sélectionnez
$oct_long = bytes::length $chaine; # doit d'abord faire un use bytes

link Image non disponible Image non disponible Image non disponible

 
Sélectionnez
link ANCIEN_FICHIER, NOUVEAU_FICHIER

Cette fonction crée un nouveau nom de fichier lié à l'ancien. La fonction renvoie vrai en cas de succès, faux sinon. Voir également symlink plus loin dans ce chapitre. Il est peu probable que cette fonction soit implémentée sur les systèmes de fichiers non Unix.

listen Image non disponible Image non disponible Image non disponible

 
Sélectionnez
listen SOCKET, TAILLE_FILE

Cette fonction informe le système que vous allez accepter des connexions sur cette SOCKET et que le système peut mettre en file d'attente le nombre de connexions spécifiées par TAILLE_FILE. Imaginez un signal d'appel sur votre téléphone, avec la possibilité de mettre 17 appels en file d'attente. (Encore faut-il le vouloir !) La fonction renvoie vrai si elle a réussi, sinon faux.

 
Sélectionnez
use Socket;
listen(SOCK_PROTO, SOMAXCONN)
    or die "Impossible de mettre une file d'attente avec listen sur SOCK_PROTO : $!";

Voir accept. Voir également la section Sockets au chapitre 16. Voir listen(2).

local

 
Sélectionnez
local EXPR

Cet opérateur ne crée pas de variable locale ; utilisez my pour le faire. À la place, il rend locales des variables existantes ; c'est-à-dire qu'il donne à une ou plusieurs variables globales une portée locale à l'intérieur du bloc, de l'eval ou du fichier le plus intérieur les encadrant. Si plus d'une valeur est listée, la liste doit être placée entre parenthèses, car la priorité de l'opérateur est plus élevée que celle des virgules. Tous les éléments listés doivent être des lvalues légales, c'est-à-dire quelque chose auquel vous pouvez assigner une valeur ; ceci peut comprendre les éléments individuels de tableaux ou de hachages.

Cet opérateur fonctionne en sauvegardant les valeurs courantes des variables spécifiées dans une pile cachée et en les restaurant au moment de sortir du bloc, du sous-programme, de l'eval ou du fichier. Après que le local a été exécuté, mais avant de sortir de sa portée, tout sous-programme ou tout format exécuté verra les valeurs locales internes et non les valeurs externes précédentes, car la variable reste globale, bien que sa valeur soit localisée. Le terme technique est « portée dynamique ». Voir la section Déclarations avec portée au chapitre 4.

On peut assigner une valeur à EXPR si besoin, ce qui permet d'initialiser vos variables au moment où vous les rendez locales. Si aucune initialisation explicite n'est effectuée, tous les scalaires sont initialisés à undef et tous les tableaux et hachages à (). Comme pour les affectations ordinaires, si l'on utilise des parenthèses autour des variables à gauche (ou si la variable est un tableau ou un hachage), l'expression de droite est évaluée dans un contexte de liste. Sinon, l'expression de droite est évaluée dans un contexte scalaire.

Dans tous les cas, l'expression de droite est évaluée avant de rendre les variables locales, mais l'initialisation est effectuée après, vous permettant ainsi d'initialiser une variable rendue locale avec la valeur qu'elle contenait avant de l'être. Par exemple, ce code démontre comment modifier temporairement un tableau global :

 
Sélectionnez
if ($op eq '-v') {
    # initialiser le tableau local avec le tableau global
    local @ARGV = @ARGV;
    unshift @ARGV, 'echo';
    system @ARGV;
}
# @ARGV restauré

Vous pouvez aussi modifier temporairement des hachages globaux :

 
Sélectionnez
# ajoute temporairement quelques entrées au hachage %chiffres
if ($base12) \{
    # (NB : ce n'est pas forcément efficace !)
    local(%chiffres) = (%chiffres, T => 10, E => 11);
    &parcours_nombres();
}

Vous pouvez utiliser local pour donner des valeurs temporaires aux éléments individuels de tableaux ou de hachages, même s'ils ont une portée lexicale :

 
Sélectionnez
if ($protege) {
    local $SIG{INT} = 'IGNORE';
    precieux();     # pas d'interruption durant cette fonction
}                   # le gestionnaire précédent (s'il y en a) est restauré

Vous pouvez utiliser local avec les typeglobs pour créer des handles de fichiers locaux sans charger des modules objets encombrants :

 
Sélectionnez
local *MOTD;                 # protège tout handle MOTD global
my $hf = do { local *HF };   # crée un nouveau handle de fichier indirect

(Depuis la version 5.6 de Perl, un my $hf; ordinaire suffit, car il vous donne une variable indéfinie là où un handle de fichier est attendu, comme le premier argument de open ou socket, Perl donne maintenant la vie à un tout nouveau handle de fichier pour vous.)

Mais en général, préférez my au lieu de local, car local n'est pas vraiment ce que la plupart des gens définit comme « local », ni même « local ». Voir my.

localtime

 
Sélectionnez
localtime EXPR
localtime

Cette fonction convertit une heure renvoyée par la fonction time en un tableau de neuf éléments dont l'heure est en phase avec le méridien local. Elle est généralement employée comme suit :

 
Sélectionnez
#  0    1     2      3     4      5      6      7       8
($sec,$min,$heure,$mjour,$mois,$annee,$sjour,$ajour,$est_dst) = localtime;

Si, comme dans ce cas, EXPR est omise, la fonction effectue localtime(time()).

Tous les éléments sont numériques et proviennent directement d'une struct tm (un jargon de programmation C — pas d'affolement). Cela signifie en particulier que $mois se situe dans l'intervalle 0..11 avec janvier comme le mois 0 et que $sjour est dans 0..6 avec dimanche comme jour 0. Vous pouvez vous rappeler de ceux qui commencent par zéro, car ce sont ceux que vous utilisez toujours comme indices dans les tableaux débutant par zéro contenant les noms des mois et des jours.

Par exemple, pour obtenir le jour actuel de la semaine :

 
Sélectionnez
$ce_jour = (qw((Dim Lun Mar Mer Jeu Ven Sam))[(localtime)[6]];

$annee est le nombre d'années depuis 1900 ; c'est-à-dire qu'en 2023, $annee vaudra 123, et pas simplement 23. Pour obtenir l'année sur 4 chiffres, il suffit d'écrire $annee+1900. Pour l'avoir sur 2 chiffres (par exemple « 01 » en 2001), utilisez sprintf("%02d", $annee % 100).

Le module Time::Local de la bibliothèque Perl contient un sous-programme, timelocal, qui peut faire la conversion dans le sens l'inverse.

Dans un contexte scalaire, localtime renvoie une chaîne ressemblant à ctime(3). Par exemple, la commande date(1) peut (presque(203)) être émulée par :

 
Sélectionnez
perl -le 'print scalar localtime';

Voir aussi la fonction strftime du le module standard POSIX pour une approche permettant de formater des dates avec une granularité plus fine. Le module Time::localtime supporte une interface orientée « par nom » pour cette fonction.

lock

 
Sélectionnez
lock CHOSE

La fonction lock place un verrou sur une variable, un sous-programme ou un objet référencé par CHOSE jusqu'à ce que le verrou sorte de la portée courante. Pour assurer une compatibilité antérieure, cette fonction n'est interne que si Perl a été compilé en autorisant les threads et si vous avez écrit use Threads. Sinon, Perl supposera qu'il s'agit d'une fonction définie par l'utilisateur. Voir le chapitre 17, Threads.

log Image non disponible Image non disponible

 
Sélectionnez
log EXPR
log

Cette fonction renvoie le logarithme naturel (c'est-à-dire en base e) de EXPR. Si EXPR est négative, une exception est générée. Pour obtenir le log dans une autre base, utilisez l'algèbre de base : le log en base-N d'un nombre est égal au log de ce nombre divisé par le log naturel de N. Par exemple :

 
Sélectionnez
sub log10 {
    my $n = shift;
    return log($n)/log(10);
}

Pour l'inverse du log, voir exp.

lstat Image non disponible Image non disponible Image non disponible

 
Sélectionnez
lstat EXPR
lstat

Cette fonction est similaire à la fonction stat de Perl (y compris en positionnant le handle de fichier spécial _), mais si le dernier composant du nom de fichier est un lien symbolique, elle agit sur le lien symbolique lui-même au lieu du fichier sur lequel pointe le lien en question. (Si les liens symboliques ne sont pas implémentés, c'est un stat normal qui est lancé en lieu et place.)

m// Image non disponible Image non disponible

 
Sélectionnez
/MOTIF/
m/MOTIF/

Il s'agit de l'opérateur de correspondance, qui interprète MOTIF comme une expression régulière. L'opérateur est évalué comme une chaîne entre guillemets plutôt que comme une fonction. Voir le chapitre 5, Recherche de motif.

map

 
Sélectionnez
map BLOC LISTE
map EXPR, LISTE

Cette fonction évalue le BLOC ou l'EXPR pour chaque élément de LISTE (en affectant localement $_ à chaque élément) et renvoie la liste composée des résultats de chacune de ces évaluations. Elle évalue BLOC ou EXPR dans un contexte de liste, ce qui fait que chaque élément de LISTE peut produire zéro, un ou plusieurs éléments dans la valeur renvoyée. Ces éléments sont tous rassemblés en une seule liste plate. Par exemple :

 
Sélectionnez
@mots = map { split ' ' } @lignes;

éclate une ligne en une liste de mots. Mais on observe souvent une correspondance bijective entre les valeurs de sortie et d'entrée :

 
Sélectionnez
@caracteres = map chr, @nombres;

convertit une liste de nombres vers leurs caractères correspondants. Voici un exemple de correspondance un-vers-deux :

 
Sélectionnez
%hachage = map { gen_clef($_) => $_ } @tableau;

qui n'est qu'une façon amusante et fonctionnelle d'écrire ceci :

 
Sélectionnez
%hachage = ();
foreach $_ (@tableau) {
    $hachage{gen_clef($_)} = $_;
}

Comme $_ est un alias (une référence implicite) pour les valeurs de la liste, on peut utiliser cette variable pour modifier les éléments dans le tableau. C'est utile et supporté bien que cela puisse générer d'étranges résultats si la LISTE n'est pas un tableau nommé. L'utilisation d'une boucle foreach habituelle dans cet objectif peut paraître plus clair. Voir également grep ; map diffère de grep en ce que map renvoie une liste composée des résultats de chaque évaluation successive de EXPR, alors que grep renvoie une liste composée de chaque valeur de LISTE pour laquelle EXPR est évaluée à vrai.

mkdir Image non disponible Image non disponible

 
Sélectionnez
mkdir REPERTOIRE, MASQUE
mkdir REPERTOIRE

Cette fonction crée le répertoire spécifié par REPERTOIRE en lui donnant les permissions spécifiées par le MASQUE numérique, modifié par le umask courant. Si l'opération réussie, elle renvoie vrai, sinon faux.

Si MASQUE est omis, on suppose un masque de 0777, qui de toute façon est ce que vous voulez dans la plupart des cas. En général, créer des répertoires avec un MASQUE permissif (comme 0777) et laisser l'utilisateur modifier cela avec son umask est une meilleure habitude plutôt que de fournir un MASQUE restrictif sans donner à l'utilisateur un moyen d'être plus permissif. L'exception à cette règle est le cas où le fichier ou le répertoire doit rester privé (les fichiers mail, par exemple). Voir umask.

Si l'appel système mkdir(2) n'est pas intégré à votre bibliothèque C, Perl l'émule en appelant le programme mkdir(1). Pour créer une longue liste de répertoires sur ce genre de système, il sera plus efficace d'appeler vous-mêmes le programme mkdir avec la liste des répertoires pour éviter de créer des palanquées de sous-processus.

msgctl Image non disponible Image non disponible

 
Sélectionnez
msgctl ID, CMD, ARG

Cette fonction invoque l'appel system msgctl(2) des IPC System V ; voir msgctl(2) pour plus de détails. Il se peut que vous deviez faire un use IPC::SysV pour obtenir les définitions de constante correctes. Si CMD vaut IPC_STAT, ARG doit alors être une variable qui contiendra la structure C msqid_ds renvoyée. Les valeurs de retour fonctionnent comme celles de ioctl et fcntl : undef pour une erreur, « 0 but true » (N.d.T. : 0, mais vrai) pour zéro ou la valeur réelle dans les autres cas.

Cette fonction n'est disponible que sur les machines qui supportent les IPC System V, ce qui s'avère bien plus rare que celles qui supportent les sockets.

msgget Image non disponible Image non disponible

 
Sélectionnez
msgget CLEF, FLAGS

Cette fonction invoque l'appel système msgget(2) des IPC System V. Voir msgget(2) pour plus de détails. La fonction renvoie l'ID de file de messages ou undef s'il y a une erreur. Avant d'appeler, vous devez écrire use IPC::SysV.

Cette fonction n'est disponible que sur les machines qui supportent les IPC System V.

msgrcv Image non disponible Image non disponible

 
Sélectionnez
msgrcv ID, VAR, TAILLE, TYPE, FLAGS

Cette fonction invoque l'appel système msgrcv(2) des IPC System V pour recevoir un message depuis la file de messages ID dans la variable VAR avec une taille maximum TAILLE. Voir msgrcv(2) pour plus de détails. Lorsqu'un message est reçu, le type de message sera la première chose dans VAR et la longueur maximale de VAR sera TAILLE plus la taille du type de message. La fonction renvoie vrai si elle réussit ou undef s'il y a une erreur. Avant d'appeler, vous devez écrire use IPC::SysV.

Cette fonction n'est disponible que sur les machines qui supportent les IPC System V.

msgsnd Image non disponible Image non disponible

 
Sélectionnez
msgsnd ID, MSG, FLAGS

Cette fonction invoque l'appel système msgsnd(2) des IPC System V pour envoyer le message MSG dans la file de messages ID. Voir msgsnd(2) pour plus de détails. MSG doit commencer par l'entier long représentant le type de message. Vous pouvez créer un message comme ceci :

 
Sélectionnez
$msg = pack "L a*", $type, $texte_du_message;

La fonction renvoie vrai si elle réussit ou undef s'il y a une erreur. Avant d'appeler, vous devez écrire use IPC::SysV.

Cette fonction n'est disponible que sur les machines qui supportent les IPC System V.

my

 
Sélectionnez
my TYPE EXPR : ATTRIBUTS
my EXPR : ATTRIBUTS
my TYPE EXPR
my EXPR

Cet opérateur déclare une ou plusieurs variables privées comme n'existant que dans le bloc, le sous-programme, l'eval ou le fichier le plus intérieur les encadrant. Si plus d'une valeur est listée, la liste doit être placée entre parenthèses, car l'opérateur lie plus fortement que la virgule. Seuls les scalaires simples ou les tableaux et les hachages complets peuvent être déclarés de cette façon.

Le nom de la variable ne peut pas être qualifié par un paquetage, car les variables de paquetage sont toutes globalement accessibles par le biais de leur table de symboles correspondante tandis que les variables lexicales sont sans rapport avec une quelconque table de symboles. À l'inverse de local, cet opérateur n'a rien à voir avec les variables globales, sinon masquer une autre variable du même nom dans sa portée (c'est-à-dire, là où la variable privée existe). Cependant, une variable globale peut toujours être atteinte sous sa forme qualifiée par paquetage ou par le biais d'une référence symbolique.

La portée d'une variable privée ne commence pas avant l'instruction qui suit sa déclaration. Elle s'étend à n'importe quel bloc contenu ensuite, jusqu'à la fin de la portée de la variable elle-même.

Cela signifie cependant que tout sous-programme que vous appelez dans la portée d'une variable privée ne peut pas la voir, à moins que le bloc qui définit le sous-programme lui-même ne fasse textuellement partie de la portée de cette variable. Le terme technique consacré est portée lexicale, nous les appelons donc souvent variables lexicales. Dans la culture C, elles sont appelées variables auto, car elles sont automatiquement allouées et désallouées respectivement à l'entrée et à la sortie de la portée.

Vous pouvez si besoin assigner une valeur à EXPR, ce qui vous permet d'initialiser les variables locales. (Si aucune initialisation explicite n'est effectuée, tous les scalaires sont initialisés à la valeur indéfinie et tous les tableaux et hachages à la liste vide). Comme pour les affectations ordinaires, si l'on utilise des parenthèses autour des variables à gauche (ou si la variable est un tableau ou un hachage), l'expression de droite est évaluée dans un contexte de liste. Sinon, l'expression de droite est évaluée dans un contexte scalaire. Par exemple, les paramètres formels de sous-programme peuvent être nommés par une affectation de liste, comme ceci :

 
Sélectionnez
my ($amis, $romains, $paysans) = @_;

Mais prenez garde à ne pas oublier les parenthèses indiquant une affectation de liste, comme ceci :

 
Sélectionnez
my $pays = @_; # Est-ce correct ou pas ?

Ici, c'est la longueur du tableau (c'est-à-dire le nombre d'arguments du sous-programme) qui est assignée à la variable, car le tableau est évalué dans un contexte scalaire. Vous pouvez cependant employer l'affectation scalaire pour un paramètre formel, tant que vous utilisez l'opérateur shift. En fait, comme les méthodes sont passées aux objets dans le premier argument, de nombreux sous-programmes méthodes commencent comme ceci :

 
Sélectionnez
sub simple_comme {
    my $obj = shift;      # affectation scalaire
    my ($a,$b,$c) = @_;   # affectation de liste
    ...
}

Si vous tentez de déclarer un sous-programme de portée lexicale avec my su b, Perl mourra avec le message que cette fonctionnalité n'a pas encore été implémentée. (Sauf si bien sûr, cette fonctionnalité a déjà été implémentée.)

Les TYPE et ATTRIBUTS sont optionnels, ce qui se justifie puisqu'ils doivent tous deux être considérés comme expérimentaux. Voici à quoi ressemble une déclaration qui les utilise :

 
Sélectionnez
my Chien $medor :oreilles(courtes) :queue(longue);

Le TYPE, s'il est spécifié, indique quelle sorte de scalaire ou de scalaires sont déclarés dans EXPR, soit directement comme une ou plusieurs variables scalaires, soit indirectement par le biais d'un tableau ou d'un hachage. Si TYPE est le nom d'une classe, on supposera que les scalaires contiennent des références à des objets de ce type, ou à des objets compatibles avec ce type. En particulier, les classes dérivées sont considérées comme compatibles. C'est-à-dire, en supposant que Colley soit dérivée de Chien, vous pouvez déclarer :

 
Sélectionnez
my Chien $lassie = new Colley;

Votre déclaration affiche que vous désirez utiliser l'objet $lassie en accord avec son appartenance à un objet Chien. Le fait que ce soit vraiment un objet Colley ne doit pas avoir d'influence tant que vous vous lui faites faire des choses de Chien. Malgré la magie des méthodes virtuelles, l'implémentation de ces méthodes de Chien peuvent très bien être dans la classe Colley, mais la déclaration ci-dessus ne parle que de l'interface et pas de l'implémentation. En théorie.

De manière intéressante, dans la version 5.6.0, la seule fois où Perl accorde une attention à la déclaration de TYPE est lorsque la classe correspondante a déclaré des champs avec le pragma use fields. Prises ensembles, ces déclarations permettent à l'implémentation d'une classe en tant que pseudohachage de « s'exhiber » au code qui se trouve à l'extérieur de la classe, permettant ainsi aux recherches dans le hachage d'être optimisées par le compilateur comme étant des recherches dans un tableau. En un sens, le pseudohachage est l'interface pour une telle classe, notre théorie reste donc intacte, si ce n'est un peu cabossée. Pour plus d'informations sur les pseudohachages, voir la section Pseudohachages au chapitre 8, Références.

À l'avenir, d'autres types de classes pourront interpréter le TYPE différemment. La déclaration de TYPE doit être perçue comme une interface de type générique qui pourra un jour être instanciée de différentes manières selon la classe. En fait, le TYPE pourra même ne pas être un nom de classe officiel. Nous réservons les noms de types en minuscules pour Perl, car l'une des manières que nous préférons pour étendre le type d'interface est d'autoriser les déclarations de type de bas niveau comme int, num, str et ref. Ces déclarations ne seront pas destinées à un typage fort ; elles seront plutôt des indications pour le compilateur, en lui disant d'optimiser le stockage de la variable en supposant que cette variable sera le plus souvent utilisée comme elle a été déclarée. La sémantique des scalaires restera à peu près la même — vous serez toujours capables d'additionner deux scalaires str (N.d.T. : chaînes) ou d'afficher un scalaire int (N.d.T. : entier), exactement comme s'ils étaient les scalaires polymorphes auxquels vous êtes familiers. Mais avec une déclaration int, Perl pourra décider de ne stocker que la valeur entière et d'oublier de sauver dans le cache la chaîne résultante comme il le fait actuellement. Les boucles avec des variables de boucle int pourront tourner plus rapidement, spécialement dans le code compilé en C. Les tableaux de nombres pourront en particulier être stockés de manière plus compacte. Comme cas limite, la fonction interne vec deviendra même obsolète alors que nous pourrons écrire des déclarations comme :

 
Sélectionnez
my bit @chaine_de_bits;

La déclaration ATTRIBUTS est encore plus expérimentale. Nous n'avons pas fait grand-chose de plus que réserver la syntaxe et prototyper l'interface interne ; voir le pragma use attributes au chapitre 31 pour plus d'informations à ce sujet. Le premier attribut que nous implémenterons est susceptible d'être constant :

 
Sélectionnez
my num $PI : constant = atan2(1,1) * 4;

Mais il y a beaucoup d'autres possibilités, comme établir des valeurs par défaut pour les tableaux et les hachages ou laisser les variables partagées entre des interpréteurs coopérants. Comme l'interface de type, l'interface d'attribut doit être perçue comme une interface générique, une sorte de cadre de travail pour inventer de nouvelles syntaxes et sémantiques. Nous ne savons pas comment Perl évoluera dans les dix prochaines années. Nous savons seulement que nous pouvons le rendre plus simple pour nous-mêmes en planifiant cela à l'avance.

Voir également local, our et la section Déclarations avec portée au chapitre 4.

new

 
Sélectionnez
new NOM_CLASSE LISTE
new NOM_CLASSE

Il n'existe pas de fonction interne new. Il s'agit plutôt d'un constructeur de méthode ordinaire (c'est-à-dire un sous-programme défini par l'utilisateur) qui est défini ou hérité par la classe NOM_CLASSE (c'est-à-dire le paquetage) pour vous laisser construire des objets de type NOM_CLASSE. Beaucoup de constructeurs sont appelés « new », mais seulement par convention, juste pour jouer un tour aux programmeurs C++ en leur faisant croire qu'ils savent ce qu'il se passe. Lisez toujours la documentation de la classe en question pour savoir comment appeler ses constructeurs ; par exemple, le constructeur qui crée une « list box » dans le widget Tk est juste appelé Listbox(). Voir le chapitre 12.

next Image non disponible

 
Sélectionnez
next ETIQUETTE
next

L'opérateur next est semblable à l'instruction continue en C ; il démarre l'itération suivante de la boucle désignée par ETIQUETTE :

 
Sélectionnez
LIGNE: while (<STDIN>) {
    next LIGNE if /^#/;     # élimine les commentaires
    ...
}

S'il y avait un bloc continue dans cet exemple, il s'exécuterait immédiatement après l'invocation de next. Lorsqu'ETIQUETTE est omise, la commande se réfère à la boucle la plus intérieure l'encadrant.

Un bloc en soi-même est sémantiquement identique à une boucle qui ne s'exécute qu'une seule fois. Ainsi next peut quitter de manière anticipée un tel bloc (via le bloc continue, s'il y en a un).

next ne peut pas être employé pour sortir d'un bloc qui renvoie une valeur, comme eval {}, sub {} ou do {}, et ne doit pas être utilisé pour sortir d'une opération grep ou map. Si les avertissements sont actifs, Perl vous préviendra si vous faites un next pour sortir d'une boucle qui est hors de votre portée lexicale, comme une boucle dans une sous-routine appelante. Voir la section Instructions de boucle au chapitre 4.

no Image non disponible

 
Sélectionnez
no MODULE LISTE

Voir l'opérateur use, qui est l'inverse de no, plus ou moins. La plupart des modules standard ne « non-importent » rien, faisant de no une « non-opération ». Les modules pragmatiques ont tendance ici à être plus serviables. Si le MODULE n'est pas trouvé, une exception est levée.

oct Image non disponible

 
Sélectionnez
oct EXPR
oct

Cette fonction interprète EXPR comme une chaîne octale et renvoie la valeur décimale équivalente. S'il se trouve que EXPR commence par « 0x », on l'interprète comme une chaîne hexadécimale à la place. Si EXPR débute par « 0b », on l'interprète comme une chaîne de chiffres binaires. Ce qui suit convertit proprement en nombres n'importe quelle chaîne en base décimale, binaire, octale ou hexadécimale dans la notation standard C ou C++ :

 
Sélectionnez
$val = oct $val id $val =~ /^0/;

Pour exécuter la fonction inverse, utilisez sprintf avec le format approprié :

 
Sélectionnez
$perms = (stat("nom_fichier"))[2] & 07777;
$perms_oct = sprintf "%lo", $perms;

La fonction oct est habituellement employée lorsqu'une donnée sous forme de chaîne, comme « 644 » doit être convertie vers un mode de fichier, par exemple. Bien que Perl convertisse automatiquement les chaînes en nombres si besoin est, cette conversion automatique suppose que l'on soit en base 10.

open Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
open HANDLE_FICHIER, MODE, LISTE
open HANDLE_FICHIER, EXPR
open HANDLE_FICHIER

La fonction open associe un HANDLE_FICHIER interne à la spécification d'un fichier externe donnée par EXPR ou LISTE. Elle peut être appelée avec un, deux ou trois arguments (ou plus si le troisième argument est une commande et que vous lancez au moins la version 5.6.1 de Perl). Si trois arguments ou plus sont présents, le deuxième argument spécifie le MODE d'accès avec lequel le fichier doit être ouvert, et le troisième argument (LISTE) fournit le véritable nom de fichier ou la commande à exécuter, en fonction du MODE. Dans le cas d'une commande, des arguments supplémentaires peuvent être fournis si vous désirez invoquer la commande directement sans impliquer un shell, un peu comme system ou exec. Sinon, la commande peut être fournie comme un seul argument (le troisième), auquel cas la décision d'invoquer le shell dépend du fait que la commande contienne ou non des métacaractères du shell. (N'utilisez pas plus de trois arguments si les arguments sont des fichiers ordinaires ; cela ne fonctionnera pas.) Si le MODE n'est pas reconnu, open lève une exception.

Si seulement deux arguments sont présents, on suppose que le mode et le nom de fichier ou de commande sont assemblés dans le second argument. (Et si vous ne spécifiez aucun mode dans le second argument, mais uniquement un nom de fichier, le fichier est alors ouvert en lecture seule pour raison de sécurité.)

Avec un seul argument, la variable scalaire de paquetage qui porte le même nom (la variable, pas le paquetage !) que le HANDLE_FICHIER, doit contenir le nom du fichier et le mode optionnel :

 
Sélectionnez
$LOG = ">fichier_journal";      # $LOG ne doit pas être déclarée avec my !
    open LOG or die "Impossible d'ouvrir le fichier journal : $!";

Mais ne faites pas cela ! Ça manque de style. Oubliez que nous en avons parlé.

La fonction open renvoie vrai si elle réussit, sinon undef. Si le open commence par un pipe sur un processus fils, la valeur de retour sera le PID de ce nouveau processus. Comme avec tout appel système, vérifiez toujours la valeur de retour de open pour être sûr qu'il a marché. Mais ce n'est pas du C ou du Java, alors n'employez pas d'instruction if alors que l'opérateur or fait très bien l'affaire. Vous pouvez également employer ||, mais dans ce cas, utilisez des parenthèses autour du open. Si vous choisissez d'omettre les parenthèses autour de l'appel de fonction pour le changer en opérateur de liste, prenez garde à bien utiliser « or die » après la liste plutôt que « || die », car la préséance de || est supérieure à celle des opérateurs de liste comme open, et le || serait lié à votre dernier argument et non à l'open tout entier :

 
Sélectionnez
open LOG, ">fichier_journal"
    || die "Impossible de créer le fichier journal : $!"; # FAUX
open LOG, ">fichier_journal"
    or die "Impossible de créer le fichier journal : $!"; # ok

Cela semble plutôt exagéré, mais généralement vous devriez insérer un quelconque caractère d'espacement pour que la fin de l'opérateur de liste vous saute aux yeux :

 
Sélectionnez
open LOG, ">fichier_journal"
    or die "Impossible de créer le fichier journal : $!";

Comme le montre cet exemple, l'argument HANDLE_FICHIER n'est souvent qu'un simple identificateur (normalement en majuscules), mais il peut aussi être une expression dont la valeur donne une référence vers le véritable handle de fichier. (La référence peut être soit une référence symbolique vers le nom du handle de fichier, soit une référence en dur vers tout objet qui puisse être interprété comme un handle de fichier.) On appelle ceci un handle de fichier indirect, et toute fonction qui prend comme premier argument un HANDLE_FICHIER accepte les handles de fichiers aussi bien indirects que directs. Mais open est spécial, car si vous lui donnez une variable indéfinie comme handle de fichier indirect, Perl définira automatiquement cette variable pour vous, c'est-à-dire qu'elle sera autovivifiée pour contenir la référence de handle de fichier adéquat. Ceci a l'avantage de fermer automatiquement le handle de fichier lorsqu'il n'y a plus de référence sur lui, généralement lorsque la variable quitte la portée courante :

 
Sélectionnez
{
    my $hf;                       # (non initialisée)
    open($hf, ">fichier_journal") # $hf est autovivifié
        or die "Impossible de créer le fichier journal : $!";
    ...                           # faites ce que vous voulez avec $hf
}                                 # fermeture de $hf ici

On peut lisiblement incorporer la déclaration my $hf à l'intérieur de l'open :

 
Sélectionnez
open my $hf, ">fichier_journal" or die

Le symbole > que vous venez de voir devant le nom de fichier est un exemple de mode. Historiquement, la forme avec deux arguments de open est apparue en premier. Le récent ajout de la forme avec trois arguments vous permet de séparer le mode du nom de fichier, qui a l'avantage d'éviter toute confusion possible entre les deux. Dans l'exemple suivant, nous savons que l'utilisateur n'essaie pas d'ouvrir un nom de fichier commençant par « > ». Nous pouvons être sûrs qu'il spécifie un MODE valant « > », ce qui ouvre en écriture le fichier indiqué par EXPR, en le créant s'il n'existait pas et en l'effaçant s'il existait déjà :

 
Sélectionnez
open(LOG, ">", "fichier_journal")
    or die "Impossible de créer le fichier journal : $!";

Dans les formes plus courtes, le nom de fichier et le mode se trouvent dans la même chaîne. La chaîne est analysée un peu comme un shell typique traite les redirections de fichiers et de pipes. La chaîne est alors examinée, par n'importe quelle extrémité si besoin, pour trouver les caractères spécifiant comment le fichier doit être ouvert. Un espace est autorisé entre le mode et le nom de fichier.

Les modes qui indiquent comment ouvrir un fichier ressemblent aux symboles de redirection du shell. Le tableau 29-1 donne une liste de ces symboles. (Pour accéder à un fichier en combinant des modes d'ouvertures non présentés dans cette table, voir la fonction de bas niveau sysopen.)

Tableau 29-1. Modes pour open

Mode

Accès en lecture

Accès en écriture

Ajout uniquement

Créer si inexistant

Vidage de l'existant

< CHEMIN

O

N

N

N

N

> CHEMIN

N

O

N

O

O

>> CHEMIN

N

O

O

O

N

+< CHEMIN

O

O

N

N

N

+> CHEMIN

O

O

N

O

O

+>> CHEMIN

O

O

O

O

N

| COMMANDE

N

O

aucun

aucun

aucun

COMMANDE |

O

N

aucun

aucun

aucun

Si le mode est « < » ou rien du tout, un fichier existant est ouvert en lecture. Si le mode est « > », le fichier est ouvert en écriture, ce qui tronque les fichiers existants et crée ceux qui n'existent pas. Si le mode est « >> », le fichier est créé si besoin et ouvert en ajout, et toutes les écritures sont automatiquement placées à la fin du fichier. Si un nouveau fichier est créé parce que vous avez utilisé « > » ou « >> » et que le fichier n'existait pas auparavant, les permissions d'accès dépendront de l'umask actuel du processus avec les règles décrites pour cette fonction. Voici quelques exemples courants :

 
Sélectionnez
open(INFO,      "fichier_de_donnees")
    || die("Impossible d'ouvrir le fichier de données : $!");
open(INFO,      "< fichier_de_donnees")
    || die("Impossible d'ouvrir le fichier de données : $!");
open(RESULTATS, "> stats_en_cours")
    || die("Impossible d'ouvrir les stats en cours : $!");
open(LOG,       ">> fichier_journal")
    || die("Impossible d'ouvrir le fichier journal : $!");

Si vous préférez la version avec moins de ponctuation, vous pouvez écrire :

 
Sélectionnez
open INFO,      "fichier_de_donnees"
    or die("Impossible d'ouvrir le fichier de données : $!");
open INFO,      "< fichier_de_donnees"
    or die("Impossible d'ouvrir le fichier de données : $!");
open RESULTATS, "> stats_en_cours"
    or die("Impossible d'ouvrir les stats en cours : $!");
open LOG,       ">> fichier_journal"
    or die("Impossible d'ouvrir le fichier journal : $!");

Lors d'une ouverture en lecture, le nom de fichier spécial « - » se réfère à STDIN. lors qu'il est ouvert en écriture, ce même nom de fichier spécial se réfère à STDOUT. Normalement, on les spécifie respectivement avec « <- » et « -> ».

 
Sélectionnez
open(ENTREE, "-" ) or die; # rouvre l'entrée standard en lecture
open(ENTREE, "<-") or die; # idem, mais explicitement
open(SORTIE, "->") or die; # rouvre la sortie standard en écriture

De cette façon, l'utilisateur peut fournir à un programme un nom de fichier qui utilisera l'entrée ou la sortie standard, mais l'auteur du programme n'a pas besoin d'écrire de code particulier pour connaître ceci.

Vous pouvez également placer un « + » devant n'importe lequel de ces trois modes pour demander un accès en lecture/écriture simultané. Cependant, le fait que le fichier soit vidé ou créé et qu'il doit déjà exister est toujours déterminé par votre choix du signe inférieur ou supérieur. Cela signifie que « +< » est toujours un meilleur choix pour des mises à jour en lecture/écriture, plutôt que le mode douteux « +> » qui viderait tout d'abord le fichier avant que vous puissiez y lire quoi que ce soit. (N'utilisez ce mode que si vous ne voulez relire que ce que vous venez d'écrire.)

 
Sélectionnez
open(DBASE, "+<base_de_donnees")
    or die "Impossible d'ouvrir la base de données en mise à jour : $!";

Vous pouvez traiter un fichier ouvert en mise à jour comme une base de données en accès direct et utiliser seek pour vous déplacer vers un nombre d'octets particulier, mais les enregistrements de longueur variable rendent généralement irréalisables l'emploi du mode lecture/écriture pour mettre à jour de tels fichiers. Voir l'option de la ligne de commande -i au chapitre 19 pour une approche différente des mises à jour.

Si le premier caractère dans EXPR est un symbole pipe, open déclenche un nouveau processus et connecte un handle de fichier en écriture seule avec la commande. De cette façon, vous pouvez écrire dans ce handle et ce que vous y écrivez sera passé à l'entrée standard de cette commande. Par exemple :

 
Sélectionnez
open(IMPRIMANTE, "| lpr -Plp1") or die "Impossible de forker : $!";
print IMPRIMANTE "truc\n";
close(IMPRIMANTE) or die "Échec de la fermeture de lpr : $?/$!";

Si le dernier caractère de EXPR est un symbole pipe, open lancera ici aussi un nouveau processus, mais cette fois connecté à un handle de fichier en lecture seule. Ceci permet à tout ce que la commande écrit sur sa sortie standard d'être passé dans votre handle pour être lu. Par exemple :

 
Sélectionnez
open(RESEAU, "netstat -i -n |") or die "Impossible de forker : $!";
while (<RESEAU>) { ... }
close RESEAU or die "Impossible de fermer netstat : $!/$?";

La fermeture explicite de tout handle de fichier pipé entraîne l'attente du processus père de la terminaison du processus fils et le retour d'un code de statut dans $? ($CHILD_ERROR). Il est également possible que close positionne $! ($OS_ERROR). Voir les exemples dans les descriptions de close et de system pour savoir comment interpréter ces codes d'erreur.

Toute commande pipée contenant des métacaractères shell comme des jokers (N.d.T. : wildcards) ou des redirections d'entrée/sortie est passée à votre shell canonique (/bin/sh sur Unix), ces constructions spécifiques au shell sont donc analysées en premier lieu. Si aucun métacaractère n'est trouvé, Perl lance le nouveau processus lui-même sans appeler le shell.

Vous pouvez également utiliser la forme à trois arguments pour démarrer des pipes. En utilisant ce style, l'équivalent des ouvertures de pipe précédentes serait :

 
Sélectionnez
open(IMPRIMANTE, "|-", "lpr -Plp1") or die "Impossible de forker : $!";
open(RESEAU, "-|", "netstat -i -n") or die "Impossible de forker : $!";

Ici le caractère moins dans le deuxième argument représente la commande du troisième argument. Ces commandes n'invoquent pas le shell, mais si vous souhaitez qu'aucun traitement du shell ne survienne, les nouvelles versions de Perl vous permettent d'écrire :

 
Sélectionnez
open(IMPRIMANTE, "|-", "lpr", "-Plp1")
    or die "Impossible de forker : $!";
open(RESEAU, "-|", "netstat", "-i", "-n")
    or die "Impossible de forker : $!";

Si vous utilisez la forme à deux arguments pour ouvrir un pipe ou la commande spéciale « - »(204), un fork implicite est réalisé en premier lieu. (Sur les systèmes qui ne savent pas fork er, ceci génère une exception. Les systèmes Microsoft ne supportaient pas le fork avant la version 5.6 de Perl.) Dans ce cas, le caractère moins représente votre nouveau processus fils, qui est une copie du père. La valeur de retour de cet open forkant est l'ID du processus fils lorsqu'elle est examinée par le père, 0 lorsque c'est par le fils et la valeur indéfinie undef si le fork échoue — auquel cas, il n'y a pas de fils. Par exemple :

 
Sélectionnez
defined($pid = open(DEPUIS_LE_FILS, "-|"))
    or die "Impossible de forker : $!";

if ($pid) {
    @lignes_pere = <DEPUIS_LE_FILS>; # code du père
} else {
    print STDOUT @lignes_fils;       # code du fils
}

Le handle de fichier se comporte normalement pour le père, mais pour le processus fils, l'entrée (ou la sortie) du père est pipée depuis (ou vers) le STDOUT (ou le STDIN) du fils. Le processus fils ne voit pas le handle de fichier du père comme étant ouvert. (Ceci est utilement indiqué par le PID de 0.)

Généralement vous devriez utiliser cette construction à la place d'un open pipé classique lorsque vous voulez exercer plus de contrôle sur la manière dont la commande pipée s'exécute (comme lorsque vous exécutez setuid) et que vous ne désirez pas examiner si les commandes shells contiennent des métacaractères. Les open pipés suivants sont fortement équivalents :

 
Sélectionnez
open HF, "| tr 'a-z' 'A-Z'";                     # pipe vers une commande shell
open HF, "|-", 'tr', 'a-z', 'A-Z';               # pipe vers une commande nue
open HF, "|-" or exec 'tr', 'a-z', 'A-Z' or die; # pipe vers un fils

tout comme celles-ci :

 
Sélectionnez
open HF, " cat -n 'fichier' |";                      # pipe vers une commande shell
open HF, "-|", 'cat', '-n' 'fichier';                # pipe vers une commande nue
open HF, "-|" or exec 'cat', '-n', 'fichier' or die; # pipe vers un fils

Pour des utilisations plus élaborées de open forké, voir la section Soliloque au chapitre 16 et Nettoyage de votre environnement au chapitre 23, Sécurité.

Lorsque vous démarrez une commande avec open, vous devez choisir soit l'entrée soit la sortie : « cmd| » pour la lecture ou « |cmd » pour l'écriture. Vous ne pouvez pas utiliser open pour démarrer une commande qui possède des pipes à la fois en entrée et en sortie, comme la notation illégale (pour le moment) « |cmd| » semblerait l'indiquer. Cependant, les routines standard de la bibliothèque IPC::Open2 et IPC::Open3 vous donne une équivalence relativement proche. Pour plus de détail sur les pipes à double sens, voir la section Communication bidirectionnelle au chapitre 16.

Vous pouvez également spécifier, dans la plus pure tradition du Bourne Shell, une EXPR commençant par >&, auquel cas le reste de la chaîne est interprété comme le nom d'un handle de fichier (ou un descripteur de fichier, s'il est numérique) que l'on doit dupliquer en utilisant l'appel système dup2(2).(205) Vous pouvez utiliser & après >, >>, +>, +>> et +<. (Le mode spécifié doit correspondre au mode du handle de fichier originel.)

Une raison pour laquelle vous pourriez vouloir faire cela serait le cas où vous disposiez d'ores et déjà un handle de fichier ouvert et que vous vouliez obtenir un autre handle de fichier qui soit réellement un duplicata du premier.

 
Sélectionnez
open(SORTIE_SAUVEE, ">&ERREUR_SAUVEE")
    or die "Impossible de dupliquer ERREUR_SAUVEE : $!";
open(MON_CONTEXTE, "<&4")
    or die "Impossible de dupliquer le descfic4 : $!";

Cela signifie que si une fonction attend un nom de fichier, mais si vous ne voulez pas lui en donner parce que vous disposez déjà d'un fichier ouvert, vous n'avez qu'à passer le handle de fichier préfixé par une esperluette. Il vaut mieux tout de même utiliser un handle pleinement qualifié, pour le cas où la fonction se trouve dans un autre paquetage :

 
Sélectionnez
une_fonction("&main::FICHIER_JOURNAL");

Une autre raison de dupliquer un handle de fichier est de rediriger temporairement un handle de fichier existant sans perdre la trace de la destination d'origine. Voici un script qui sauvegarde, redirige et restaure STDOUT et STDERR :

 
Sélectionnez
#!/usr/bin/perl
open SORTIE_SAUVEE, ">&STDOUT";
open ERREUR_SAUVEE, ">&STDERR";

open STDOUT, ">truc.out" or die "Impossible de rediriger stdout";
open STDERR, ">&STDOUT" or die "Impossible de dupliquer stdout";

select STDERR; $| = 1;      # active le vidage de tampon automatique
select STDOUT; $| = 1;      # active le vidage de tampon automatique

print STDOUT "stdout 1\n";  # ces flux d'entrée/sortie se propagent
print STDERR "stderr 1\n";  # également aux sous-processus
system ("une commande");    # utilise les nouveaux stdout/stderr

close STDOUT;
close STDERR;

open STDOUT, ">&SORTIE_SAUVEE";
open STDERR, ">&ERREUR_SAUVEE";

print STDOUT "stdout 2\n";
print STDERR "stderr 2\n";

Si le handle ou le descripteur de fichier est précédé par une combinaison &= au lieu d'un simple &, alors au lieu de créé un descripteur de fichier complètement neuf, Perl fait de HANDLE_FICHIER un alias du descripteur existant en utilisant l'appel fdopen(3) de la bibliothèque C. Ceci est quelque peu plus parcimonieux en terme de ressources système, bien que ce ne soit plus un gros problème de nos jours.

 
Sélectionnez
$df = $ENV{"DF_MON_CONTEXTE"};
open(MON_CONTEXTE, "<&=$num_df"
    or die "fdopen sur le descripteur $num_fd impossible : $!\";

Les handles de fichiers STDIN, STDOUT et STDERR restent toujours ouvert à travers un exec. Les autres handles de fichiers ne le restent pas, par défaut. Sur les systèmes qui supportent la fonction fcntl, vous pouvez modifier le flag close-on-exec (N.d.T. : indicateur de fermeture lors d'un exec) pour un handle de fichier :

 
Sélectionnez
use Fcntl qw(F_GETFD F_SETFD);
$flags = fcntl(HF, F_SETFD, 0)
    or die "Impossible de nettoyer le flag close-on-exec pour HF : $!\n";

Voir aussi la variable spéciale $^F ($SYSTEM_MAX_FD) au chapitre 28.

Avec les formes à un ou à deux arguments de open, vous devez faire attention lorsque vous utilisez une variable chaîne comme nom de fichier, puisque la variable peut contenir arbitrairement des caractères étranges (particulièrement lorsque le nom du fichier a été obtenu à partir d'étranges caractères depuis Internet). Si vous n'y prenez pas garde, certaines parties du nom de fichier peuvent être interprétées comme une chaîne de MODE , des espaces à ignorer, une spécification de duplication ou un signe moins. Voici une manière historiquement intéressante de vous isoler :

 
Sélectionnez
$chemin =~ s#^(\s)#./$1#;
open (HF, "< $chemin\0") or die "Impossible d'ouvrir $chemin : $!";

Mais vous êtes toujours vulnérables de plusieurs manières. À la place, utilisez la forme à trois arguments de open pour ouvrir proprement tout nom fichier arbitraire et sans aucun risque (supplémentaire) concernant la sécurité :

 
Sélectionnez
open(HF, "<", $chemin) or die "Impossible d'ouvrir $chemin : $!";

D'un autre côté, si ce que vous recherchez est un véritable appel système dans le style de open(2) en C, avec les cloches et sirènes d'arrêt qui s'en suivent, alors investissez sur sysopen :

 
Sélectionnez
use Fcntl;
sysopen(HF, $chemin, O_RDONLY) or die "Impossible d'ouvrir $chemin : $!";

Si vous êtes sur un système qui fait la distinction entre les fichiers textes et binaires, vous pouvez avoir besoin de placer votre handle de fichier en mode binaire — ou oubliez de faire cela, comme cela peut s'avérer — pour éviter de mutiler vos fichiers. Sur de tels systèmes, si vous utilisez le mode texte avec des fichiers binaires, ou l'inverse, vous n'apprécierez certainement pas les résultats.

Les systèmes qui ont besoin de la fonction binmode se distinguent des autres par le format employé pour les fichiers textes. Ceux qui s'en passent finissent chaque ligne avec un seul caractère correspondant à ce que le C pense être un saut de ligne, \n. Unix et Mac OS tombent dans cette catégorie. Les systèmes d'exploitation des autres variétés VMS, MVS, MS-biduletrucmachinchouette et S&M traitent différemment les entrées/sorties dans les fichiers textes et binaires, ils ont donc besoin de binmode.

Ou de son équivalent. Depuis la version 5.6 de Perl, vous pouvez spécifier le mode binaire dans la fonction open sans un appel séparé à binmode. En tant que composantes de l'argument MODE (mais uniquement dans la forme à trois arguments), vous pouvez spécifier diverses disciplines d'entrées/sorties. Pour obtenir l'équivalent d'un binmode, employez la forme à trois arguments de open et donnez une discipline valant :raw après les autres caractères de MODE :

 
Sélectionnez
open(HF, "<:raw", $chemin) or die "Impossible d'ouvrir $chemin : $!";

Puisqu'il s'agit d'une toute nouvelle fonctionnalité, il existera certainement plus de disciplines au moment où vous lirez ceci que lorsque nous l'avons écrit. Cependant, nous pouvons raisonnablement prédire qu'il y aura en toute vraisemblance des disciplines qui ressembleront pour toutes ou partie à celles du tableau 29-2.

Tableau 29-2. Disciplines d'entrées/sorties

Discipline

Signification

:raw

Mode binaire ; ne pas traiter.

:text

Traitement par défaut de texte.

:def

Défaut déclaré par « use open ».

:latin1

Le fichier doit être en ISO-8859-1.

:ctype

Le fichier doit être en LC_TYPE.

:utf8

Le fichier doit être en UTF-8.

:utf16

Le fichier doit être en UTF-16.

:utf32

Le fichier doit être en UTF-32.

:uni

Pressent de l'Unicode (UTF-*).

:any

Pressent de l'Unicode/Latin1/LC-CTYPE.

:xml

Utilise l'encodage spécifié dans le fichier.

:crlf

Pressent des sauts de lignes.

:para

Mode paragraphe.

:slurp

Mode par avalement tout rond.

Vous serez capables d'empiler les disciplines susceptibles d'être empilées, ainsi, vous pourrez écrire par exemple :

 
Sélectionnez
open(HF, "<:para:crlf:uni", $chemin)
    or die "Impossible d'ouvrir $chemin : $!";
while ($para ) <HF>) { ... }

Ceci positionnera les disciplines :

  • en lisant certaines formes d'Unicode et en les convertissant vers le format interne de Perl UTF-8 si le fichier n'est pas d'ores et déjà en UTF-8 ;
  • en cherchant les variantes des séquences de fin de ligne et en les convertissant toutes vers \n, et ;
  • en traitant le fichier paragraphe par paragraphe, un peu comme le fait $/="".

Si vous voulez positionner le mode d'ouverture par défaut (:def) à autre chose que :, vous pouvez déclarer ceci au tout début de votre fichier avec le pragma open :

 
Sélectionnez
use open IN => ":any", OUT => ":utf8";

En fait, ce serait vraiment beau si un jour ou l'autre c'était la discipline : par défaut. Ceci reflète bien l'esprit du dicton : « Soyez tolérant avec ce que vous acceptez et strict avec ce que vous produisez.

opendir Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
opendir HANDLE_REPERTOIRE, EXPR

Cette fonction ouvre un répertoire nommé EXPR pour le traiter par readdir, telldir, seekdir, rewinddir et closedir. La fonction renvoie vrai en cas de réussite. Les handles de répertoires possèdent leur propre espace de nommage, séparé de celui des handles de fichiers.

ord Image non disponible

 
Sélectionnez
ord EXPR
ord

Cette fonction renvoie la valeur numérique (ASCII, Latin-1 ou Unicode) du premier caractère de EXPR. La valeur de retour est toujours non signée. Si vous désirez une valeur signée, utilisez unpack('c',EXPR). Si vous voulez convertir tous les caractères de la chaîne en une liste de nombres, utilisez unpack('U*', EXPR) à la place.

our

 
Sélectionnez
our TYPE EXPR : ATTRIBUTS
our EXPR : ATTRIBUTS
our TYPE EXPR
our EXPR

Un our déclare une ou plusieurs variables comme étant des variables globales valides à l'intérieur du bloc, du fichier ou de l'eval l'encadrant. C'est-à-dire que l'on détermine la visibilité de our avec les mêmes règles qu'une déclaration my. Mais our ne crée pas de variable privée ; il permet simplement l'accès sans entraves à la variable de paquetage globale existante. Si plus d'une valeur est listée, la liste doit être placée entre parenthèses.

L'utilisation principale d'un our est de cacher la variable des effets d'une déclaration use strict "vars" ; puisque la variable est masquée comme une variable my, vous avez la permission d'utiliser la variable déclarée globale sans la qualifier avec son paquetage. Cependant, tout comme une variable my, cela ne marche que dans la portée lexicale de la déclaration our. En regard de ceci, our diffère de use vars, qui affecte le paquetage dans son entier et qui n'a pas de portée lexicale.

our est également semblable à my en ce que vous êtes autorisé à déclarer une variable avec un TYPE et des ATTRIBUTS. Voici la syntaxe :

 
Sélectionnez
our Chien $medor :oreilles(courtes) :queue(longue);

Au moment où nous écrivons ceci, sa signification n'est pas tout à fait claire. Les attributs peuvent affecter soit la variable globale, soit l'interprétation locale de $medor. D'un côté, cela ressemblerait fort aux variables my pour les attributs que l'on protège d'un voile dans la vue locale actuelle de $medor, sans interférer avec les autres vues de la variable globale à d'autres endroits. De l'autre côté, si un module déclare $medor comme étant un Chien et qu'un autre déclare $medor en tant que Chat, vous pouvez finir avec des chiens miaulant et des chats aboyant. C'est un sujet de recherche active, ce qui est une manière polie de dire que nous ne savons pas de quoi nous parlons à l'heure actuelle. (Excepté que nous savons quoi faire avec une déclaration de TYPE lorsque la variable se réfère à un pseudohachage — voir Gestion des données d'instance au chapitre 12.)

Une autre similitude entre our et my réside dans sa visibilité. Une déclaration our déclare une variable globale qui sera visible tout au long de sa portée lexicale, même au-delà des frontières de paquetages. Le paquetage dans lequel la variable est située est déterminé à l'endroit de la déclaration, pas à l'endroit où on l'utilise. Cela signifie que le comportement suivant est valide et qu'il est jugé être une fonctionnalité :

 
Sélectionnez
package Truc;
our $machin;   # $machin est $Truc::machin pour le reste de la
               # portée lexicale
$machin = 582;

package Machin
print $machin; # $affiche 582, comme si 'our' avait été 'my'

Toutefois, la distinction entre my qui crée une nouvelle variable privée et our qui expose une variable globale existante est importante, particulièrement pour les affectations. Si vous combinez une affectation à l'exécution avec une déclaration our, la valeur de la variable globale ne disparaîtra pas une fois que le our sortira de la portée. Pour cela, vous avez besoin de local :

 
Sélectionnez
($x, $y) = ("un", "deux");
print "avant le bloc, x vaut $x, y vaut $y\n";
{
    our $x = 10;
    local our $y = 20;
    print "dans le bloc, x vaut $x, y vaut $y\n";
}
print "après le bloc, x vaut $x, y vaut $y\n";

Cela affiche :

 
Sélectionnez
avant le bloc, x vaut un, y vaut deux
dans le bloc, x vaut 10, y vaut 20
après le bloc, x vaut 10, y vaut deux

De multiples déclarations our dans la même portée sont autorisées si elles se trouvent dans des paquetages différents. Si elles se produisent dans le même paquetage, Perl émettra des avertissements, si vous lui demandez de le faire.

 
Sélectionnez
use warnings;
package Truc;
our $machin;      # déclare $Truc::machin pour le reste de la
                  # portée lexicale
$machin = 20;

package Machin;
our $machin = 30; # déclare $Machin::machin pour le reste de la
                  # portée lexicale
print $machin;    # affiche 30

our $machin;      # émet un avertissement

Voir aussi local, my et la section Déclarations avec portée au chapitre 4.

pack Image non disponible

 
Sélectionnez
pack CANEVAS, LISTE

Cette fonction prend une LISTE de valeurs ordinaires Perl, les convertit en une chaîne d'octets en fonction du CANEVAS et renvoie cette chaîne. La liste d'arguments est complétée ou tronquée selon les besoins. C'est-à-dire que si vous fournissez moins d'arguments que n'en requiert le CANEVAS, pack suppose que les arguments additionnels sont nuls. À l'inverse, si vous fournissez plus d'arguments que n'en requiert le CANEVAS, les arguments supplémentaires sont ignorés. Les formats inconnus du CANEVAS génèreront des exceptions.

Le CANEVAS décrit une structure de chaîne en tant que séquence de champs. Chaque champ est représenté par un seul caractère qui décrit le type de la valeur et son encodage. Par exemple, un caractère de format valant N spécifie un entier non signé de quatre octets dans l'ordre de la notation gros-boutiste (N.d.T. : big-endian).

Les champs sont empaquetés dans l'ordre donné par le CANEVAS. Par exemple, pour empaqueter un entier signé d'un octet et un nombre en virgule flottante avec une simple précision dans une chaîne, vous devez écrire :

 
Sélectionnez
$chaine = pack("Cf", 244, 3.14);

Le premier octet de la chaîne renvoyée a la valeur 244. Les octets restants représentent l'encodage de 3.14 en tant que nombre flottant en simple précision. L'encodage particulier du nombre à virgule flottante dépend du matériel de votre ordinateur.

Les points importants à considérer lorsque vous utilisez pack sont :

  • le type de donnée (comme un entier, un nombre à virgule flottante ou une chaîne) ;
  • l'intervalle de valeurs (comme lorsque vos entiers occupent un, deux, quatre ou peut-être même huit octets ; ou si vous empaquetez des caractères 8-bits ou Unicode) ;
  • si vos entiers sont signés ou non ;
  • l'encodage à employer (comme un empaquetage de bits ou d'octets en natif, en petit-boutiste ou en gros-boutiste.

Le tableau 29-3 liste les caractères de format et leurs significations. (D'autres caractères peuvent apparaître dans les formats ; ils seront décrits plus tard.)

Tableau 29-3. Caractères de canevas pour pack/unpack

Caractère

Signification

a

Une chaîne d'octets, complétée par des nuls.

A

Une chaîne d'octets, complétée par des blancs.

b

Une chaîne de bits, dans l'ordre croissant des bits à l'intérieur de chaque octet (comme vec).

B

Une chaîne de bits, dans l'ordre décroissant des bits à l'intérieur de chaque octet.

c

Une valeur caractère signée (entier 8-bits).

C

Une valeur caractère non signé (entier 8-bits) ; voir U pour Unicode.

d

Un nombre à virgule flottante en double précision au format natif.

f

Un nombre à virgule flottante en simple précision au format natif.

h

Une chaîne hexadécimale, quartet de poids faible d'abord.

H

Une chaîne hexadécimale, quartet de poids fort d'abord.

i

Une valeur entière signée au format natif.

I

Une valeur entière non signée au format natif.

l

Une valeur entière longue signée, toujours de 32 bits.

L

Une valeur entière longue non signée, toujours de 32 bits.

n

Un court de 16 bits, dans l'ordre « réseau » (gros-boutiste).

N

Un long de 32 bits, dans l'ordre « réseau » (gros-boutiste).

p

Un pointeur sur une chaîne terminée par un caractère nul.

P

Un pointeur sur une chaîne de longueur fixe.

q

Une valeur quad (entier de 64 bits) signée.

Q

Une valeur quad (entier de 64 bits) non signé.

s

Une valeur entière courte signée, toujours de 16 bits.

S

Une valeur entière courte non signée, toujours de 16 bits.

u

Une chaîne uuencodée.

U

Un nombre en caractère Unicode.

v

Un court de 16 bits dans l'ordre « VAX » (petit-boutiste).

V

Un long de 32 bits dans l'ordre « VAX » (petit-boutiste).

w

Un entier compressé au format BER.

x

Un octet nul (avance d'un octet).

X

Recule d'un octet.

Z

Une chaîne d'octets terminée par un caractère nul (et complétée par des nuls).

@

Remplissage avec un caractère nul à la position absolue.

Vous pouvez librement placer des espaces et des commentaires dans vos CANEVAS. Les commentaires commencent par le symbole # habituel et se prolongent jusqu'à la première fin de ligne (s'il y en a) dans le CANEVAS. Chaque lettre peut être suivie par un nombre indiquant le compteur, que l'on interprète comme le compteur de répétitions ou la longueur en quelque sorte, selon le format. Avec tous les formats exceptés a, A, b, B, h, H, P et Z, compteur est un compteur de répétition, pack engloutit autant de valeurs dans la LISTE. Un * pour le compteur signifie autant d'entités qu'il en reste.

Les formats a, A et Z n'engloutissent qu'une seule valeur, mais l'empaquettent comme une chaîne d'octets de longueur compteur, en la complétant avec des caractères nuls ou des espaces si besoin. Lorsqu'on dépaquette, A dépouille les espaces et les caractères nuls qui traînent, Z dépouille tout ce qui se trouve après le premier caractère nul et a renvoie la donnée littérale indemne. Lorsqu'on empaquette, a et Z sont équivalents.

De même, les formats b et B empaquettent une chaîne longue de compteur bits. Chaque octet du champ d'entrée génère 1 bit dans le résultat basé sur le bit le moins significatif de chaque octet d'entrée (c'est-à-dire, sur ord($octet) % 2). Commodément, cela signifie que les octets 0 et 1 génèrent les bits 0 et 1. En partant du début de la chaîne d'entrée, chaque 8-tuple d'octets est converti vers un unique octet en sortie. Si la longueur de la chaîne d'entrée n'est pas divisible par 8, le reste est empaqueté comme s'il était complété par des 0s. De même, durant le dépaquetage avec unpack les bits supplémentaires sont ignorés. Si la chaîne d'entrée est plus longue que nécessaire, les octets supplémentaires sont ignorés. Un * comme compteur signifie l'utilisation de tous les octets du champ d'entrée. Durant le dépaquetage avec unpack, les bits sont convertis vers une chaîne de 0 s et de 1 s.

Les formats h et H empaquettent une chaîne de compteur quartets (groupes de 4 bits souvent représentés comme des chiffres hexadécimaux).

Le format p empaquette un pointeur sur une chaîne terminée par un caractère null. Il vous incombe de vous assurer que la chaîne n'est pas une valeur temporaire (qui est susceptible d'être désallouée avant que vous n'ayez fini d'utiliser le résultat empaqueté) Le format P empaquette un pointeur vers une structure dont la taille est indiquée par compteur. Un pointeur nul est créé si la valeur correspondante pour p ou P est undef.

Le caractère / permet d'empaqueter et de dépaqueter des chaînes dans lesquelles la structure empaquetée contient un compteur sur un octet suivi par la chaîne elle-même. On écrit entité-longueur/entité-chaîne. L'entité-longueur peut être n'importe quelle lettre canevas de pack et décrit comment la valeur représentant la longueur est empaquetée. Les canevas les plus susceptibles d'être utilisés sont ceux empaquetant des entiers comme n (pour les chaînes Java), w (pour de l'ASN.1 ou du SNMP) et N (pour du XDR de Sun). L'entité-chaîne doit, à présent, être A*, a* ou Z*. Pour unpack, la longueur de la chaîne est obtenue à partir de l'entité-longueur, mais si vous avez mis un *, elle sera ignorée.

 
Sélectionnez
unpack 'C/a', "\04Gurusamy";            # donne 'Guru'
unpack 'a3/A* A*', '007 Bond J ';       # donne ('Bond','J')
pack 'n/a* w/a*','bonjour,','le monde'; # donne "bonjour, le monde"

unpack ne renvoie pas explicitement l'entité-longueur. L'ajout d'un compteur à la lettre de l'entité-longueur n'est pas susceptible d'être utile à quoi que ce soit, sauf si cette lettre est A, a ou Z. L'empaquetage avec une entité-longueur de a ou Z introduit des caractères nuls (\0), que Perl ne considère pas comme légaux dans les chaînes numériques.

Les formats d'entiers s, S, l et L peuvent être immédiatement suivis par un ! pour signifier des entiers courts ou longs natifs à la place de mesurer exactement 16 et 32 bits, respectivement. À ce jour, c'est un problème principalement pour les plates-formes 64 bits, où les entiers cours et longs natifs tel que les voit le compilateur local C peuvent être complètement différents de ces valeurs. (i! et I! fonctionnent, mais seulement à cause de la complétude ; ils sont identiques à i et I.)

La taille réelle (en octets) des entiers, des courts, des longs et des « longs longs » natifs sur la plate-forme où Perl a été compilé est également disponible via le module Config :

 
Sélectionnez
use Config;
print $Config{shortsize},    "\n";
print $Config{intsize},      "\n";
print $Config{longsize},     "\n";
print $Config{longlongsize}, "\n";

Le simple fait que Configure connaisse la taille d'un « long long », n'implique pas forcément que vous disposiez des formats q et Q. (Certains systèmes en disposent, mais vous n'en possédez certainement pas. Du moins pas encore.)

Les formats d'entiers d'une longueur plus grande qu'un seul bit (s, S, i, I, l et L) sont intrinsèquement non portables entre processeurs différents, car ils obéissent à l'ordre des octets natifs et au paradigme petit-boutiste/gros-boutiste. Si vous voulez des entiers portables, utilisez les formats n, N, v et V ; l'ordre de leurs bits et leur taille sont connus.

Les nombres à virgules flottantes ne se trouvent que dans le format natif de la machine. À cause de la variété des formats des flottants et de l'absence d'une représentation « réseau » standard, il n'existe pas d'interéchanges facilités. Cela signifie que si l'on écrit des données à virgule flottante empaquetées sur une machine, elles pourront ne pas être lisibles sur une autre. Ceci est un problème même lorsque les deux machines utilisent l'arithmétique flottante IEEE, car l'ordre (petit-boutiste/gros-boutiste) de la représentation en mémoire ne fait pas partie de la spécification IEEE.

Perl utilise en interne des doubles pour tous les calculs en virgule flottante, donc la conversion depuis un double vers un float, puis la conversion inverse perdra de la précision. Cela signifie que unpack("f", pack("f", $truc)) ne sera généralement pas égal à $truc.

Vous êtes responsable de toute considération concernant les alignements ou les remplissages exigés par d'autres programmes, particulièrement par ces programmes créés par un compilateur C avec sa propre idiosyncrasie en matière de présentation d'une struct C sur l'architecture particulière en question. Vous devrez ajouter suffisamment de x durant l'empaquetage pour compenser ceci. Par exemple, une déclaration C de :

 
Sélectionnez
struct machin {
    unsigned char c;
    float f;
}

pourrait être écrite dans un format « Cxf », ou « C x3 f », ou encore « fC » — pour n'en citer que quelques-uns. Les fonctions pack et unpack gèrent leurs entrées et leurs sorties comme des séquences plates d'octets, car il n'y a aucun moyen pour elles de savoir où vont les octets, n d'où ils viennent.

Regardons quelques exemples. Cette première paire empaquette des valeurs numériques dans des octets :

 
Sélectionnez
$sortie = pack "CCCC", 65, 66, 67, 68;  # $sortie eq "ABCD"
$sortie = pack "C4", 65, 66, 67, 68;    # idem

Celui-ci fait la même chose avec des lettres Unicode :

 
Sélectionnez
$machin = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9);

Celui-là est similaire, avec une paire de caractères nuls rentrant en jeu :

 
Sélectionnez
$sortie = pack "CCxxCC", 65, 66, 67, 68 # $sortie eq "AB\0\0CD"

Empaqueter vos entiers courts n'implique pas que vous soyez portable :

 
Sélectionnez
$sortie = pack "s2", 1, 2; # "\1\0\2\0" en petit-boutiste
                           # "\0\1\0\2" en gros-boutiste

Dans les paquets binaires et hexadécimaux, le compteur se réfère au nombre de bits ou de quartets, pas au nombre d'octets produits :

 
Sélectionnez
$sortie = pack "B32", "01010000011001010111001001101100";
$sortie = pack "H8", "5065726c";    # les deux donnent "Perl"

La longueur dans un champ a ne s'applique qu'à une seule chaîne :

 
Sélectionnez
$sortie = pack "a4", "abcd", "x", "y", "z";     # "abcd"

Pour contourner cette limitation, utilisez plusieurs spécificateurs :

 
Sélectionnez
$sortie = pack "aaaa", "abcd", "x", "y", "z";  # "axyz"
$sortie = pack "a" x 4, "abcd", "x", "y", "z"; # "axyz"

Le format a rempli avec des caractères nuls

 
Sélectionnez
$sortie = pack "a14", "abcdefg"; # "abcdefg\0\0\0\0\0\0\0"

Ce canevas empaquette un enregistrement de struct tm C (du moins sur certains systèmes) :

 
Sélectionnez
$sortie = pack "i9pl", gmtime(), $tz, $toff;

Généralement, le même canevas peut également être utilisé dans la fonction unpack, bien que certains formats se comportent différemment, notamment a, A et Z. Si vous voulez joindre des champs de texte de taille fixe, utilisez pack avec un CANEVAS

de format A ou a :

 
Sélectionnez
$chaine = pack("A10" x 10, @data);

Si vous voulez joindre des champs de texte de taille variable avec un séparateur, utilisez plutôt la fonction join :

 
Sélectionnez
$chaine = join(" and ", @donnee);
$chaine = join("", @donnee);  # séparateur nul

Bien que tous nos exemples utilisent des chaînes littérales comme canevas, il n'y a rien qui vous interdise d'aller chercher vos données dans un fichier sur disque. Vous pouvez construire une base de données relationnelle complète autour de cette fonction. (Nous ne nous étendrons pas sur ce que cela prouverait sur votre nature.)

package

 
Sélectionnez
package ESPACE_DE_NOM
package

Il ne s'agit pas vraiment d'une fonction, mais d'une déclaration qui affirme que le reste de la portée la plus intérieure l'encadrant appartient à la table de symboles ou l'espace de nom, indiqué. (La portée d'une déclaration package est ainsi la même que la portée d'une déclaration my ou our.) À l'intérieur de cette portée, la déclaration force le compilateur à résoudre tous les identificateurs non qualifiés en les recherchant dans la table de symboles du paquetage déclaré.

Une déclaration package n'affecte que les variables globales — y compris celles sur lesquelles vous avez employé local — et pas les variables lexicales déclarées avec my. Elle affecte seulement les variables globales non qualifiées ; celles qui sont qualifiées avec leur propre nom de paquetage ignorent le paquetage actuellement déclaré. Les variables globales déclarées avec our ne sont pas qualifiées et respectent par conséquent le paquetage courant, mais seulement à l'endroit de leur déclaration, après quoi elles se comportent comme des variables my. C'est-à-dire que pour le reste de leur portée lexicale, les variables our sont « clouées » au paquetage courant au moment de leur déclaration, même si une déclaration de paquetage ultérieure intervient.

La déclaration package est généralement la première d'un fichier à inclure avec un opérateur require ou use, bien qu'elle puisse se trouver en tout endroit légal pour une instruction. Lorsqu'on crée un fichier de module traditionnel ou orienté objet, il est courant d'appeler le paquetage avec le même nom que le fichier pour éviter toute confusion. (Il est également courant de mettre la première lettre du nom du paquetage en majuscule, car les modules en minuscules sont interprétés par convention comme étant des pragmas.)

Vous pouvez passer dans un paquetage donné par plus d'un endroit ; cela influence le choix de la table des symboles utilisée par le compilateur pour le reste de ce bloc. (Si le compilateur rencontre un autre paquetage déclaré au même niveau, la nouvelle déclaration écrase l'ancienne.) Votre programme principal est censé commencer par une déclaration package main.

Vous pouvez vous référer à des variables, des sous-programmes, des handles de fichier et des formats appartenant à d'autres paquetages en préfixant l'identificateur avec le nom du paquetage et un double deux-points : $Paquetage::Variable. Si le nom du paquetage est nul, le paquetage principal est pris par défaut. C'est-à-dire que $::heureuse est équivalente à $main::heureuse, tout comme à $main'heureuse, que l'on rencontre encore parfois dans d'anciens codes.

Voici un exemple :

 
Sélectionnez
package main; $heureuse = "un poker de dames";
package Donne; $heureuse = "truquée";
package Nimporte;
print "Ma main heureuse est $main::heureuse.\n";
print "La donne heureuse est $Donne::heureuse.\n";

Ce qui affiche :

 
Sélectionnez
Ma main heureuse est un poker de dames.
Ma donne heureuse est truquée.

La table de symboles d'un paquetage est stockée dans un hachage avec un nom se terminant par un double deux-points. La table de symboles du paquetage principal est par exemple appelée %main::. On peut donc aussi accéder au symbole *main::heureuse par $main::{"heureuse"}.

Si ESPACE_DE_NOM est omis, il n'y aura alors aucun paquetage courant et tous les identifiants devront être pleinement qualifiés ou déclarés comme lexicaux. C'est encore plus strict qu'un use strict, puisque cela s'étend également aux noms de fonctions.

Voir le chapitre 10, Paquetages, pour plus d'informations sur les paquetages. Voir my plus haut dans ce chapitre pour d'autres considérations sur les portées.

pipe Image non disponible Image non disponible Image non disponible

 
Sélectionnez
pipe HANDLE_LECTURE, HANDLE_ECRITURE

Comme l'appel système correspondant, cette fonction ouvre deux pipes connectés, voir pipe(2). Cet appel est presque toujours employé avant un fork, après lequel le lecteur du pipe doit fermer HANDLE_ECRITURE et celui qui écrit doit fermer HANDLE_LECTURE. (Sinon le pipe n'indiquera pas la fin de fichier à celui qui lit quand celui qui écrit le fermera.) Si vous lancez une boucle de processus par des pipes, un verrou mortel peut se produire à moins d'être très prudent. Notez de plus que les pipes de Perl utilisent des tampons d'entrées/sorties standard et qu'il vous faut donc positionner $| ($OUTPUT_AUTOFLUSH) sur votre HANDLE_ECRITURE pour vider les tampons après chaque opération de sortie, selon l'application - voir select (handle de fichier de sortie).

(Comme avec open, si l'un des handle de fichier est indéfini, il sera autovivifié.)

Voici un petit exemple :

 
Sélectionnez
pipe(LISEZ_MOI, ECRIVEZ_MOI);
unless ($pid = fork) { # fils
    defined $pid or die "Impossible de forker : $!";
    close(LISEZ_MOI);
    for $i (1..5) { print ECRIVEZ_MOI "ligne $i\n" }
    exit;
}
$SIG{CHLD} = sub { waitpid($pid, 0) };
close(ECRIVEZ_MOI);
@chaines = <LISEZ_MOI>;
close(LISEZ_MOI);
print "Reçu: \n", @chaines;

Remarquez comment l'écrivain ferme l'extrémité de lecture et comment à l'inverse le lecteur ferme l'extrémité d'écriture. Vous ne pouvez pas utiliser un seul pipe pour une communication à double sens. Utilisez pour cela soit deux pipes différents, soit l'appel système socketpair. Voir la section Pipes au chapitre 16.

pop

 
Sélectionnez
pop TABLEAU
pop

Cette fonction traite un tableau comme une pile — elle dépile (enlève) et renvoie la dernière valeur du tableau en le raccourcissant d'un élément. Si TABLEAU est omis, la fonction dépile @_ dans la portée lexicale des sous-programmes et formats ; elle dépile @ARGV dans la portée des fichiers (généralement le programme principal) ou à l'intérieur de la portée lexicale établie par les constructions eval CHAINE, BEGIN {}, CHECK {}, INIT {} et END {}. Elle entraîne les mêmes effets que :

 
Sélectionnez
$tmp = $TABLEAU{$#TABLEAU--};

ou que :

 
Sélectionnez
$tmp = splice @TABLEAU, -1;

S'il n'y a pas d'élément dans le tableau, pop renvoie undef. (Mais ne vous basez pas sur ceci pour vous dir que le tableau est vide si votre tableau continent des valeurs undef !) Voir également push et shift. Pour dépiler plus d'un élément, utilisez splice.

Le premier argument de pop doit être un tableau et non une liste. Pour obtenir le dernier élément d'une liste, utilisez ceci :

 
Sélectionnez
( LISTE )[-1]

pos Image non disponible

 
Sélectionnez
pos SCALAIRE
pos

Cette fonction renvoie l'endroit de SCALAIRE où la dernière recherche m//g s'est arrêtée. Elle renvoie le décalage du caractère suivant celui qui correspondait. (C'est-à-dire que c'est équivalent à length($`) + length($&).) Il s'agit du décalage où la prochaine recherche m//g sur cette chaîne démarrera. Rappelez-vous que le décalage début de la chaîne est 0. Par exemple :

 
Sélectionnez
$grafitto = "fee fie foe foo";
while ($grafitto =~ m/e/g) {
    print pos $grafitto, "\n";
}

affiche 2, 3, 7 et 11, les décalages de chacun des caractères suivant un « e » . On peut assigner à pos une valeur pour indiquer à m//g d'où partir :

 
Sélectionnez
$grafitto = "fee fie foe foo";
pos $grafitto = 4; # Sauter le fee, commencer à fie
while ($grafitto =~ m/e/g) {
    print pos $grafitto, "\n";
}

Cela n'affiche que 7 et 11. L'assertion \G ne recherche de correspondance qu'à l'endroit spécifié par pos à ce moment dans la chaîne dans laquelle on recherche. Voir la section Positions au chapitre 5.

print Image non disponible Image non disponible Image non disponible

 
Sélectionnez
print HANDLE _FICHIER LISTE
print LISTE
print

Cette fonction affiche une chaîne ou une liste de chaînes séparées par des virgules. Si la variable $\ ($OUTPUT_RECORD_SEPARATOR) est positionnée, son contenu sera affiché implicitement à la fin de la liste. La fonction renvoie vrai en cas de réussite, sinon faux. HANDLE_FICHIER peut être un nom de variable scalaire (non indicée), auquel cas la variable contient le nom du véritable handle de fichier ou une référence à un objet handle de fichier d'une quelconque sorte. HANDLE_FICHIER peut également être un bloc qui renvoie une telle valeur :

 
Sélectionnez
print { $OK ? "STDOUT" : "STDERR" } "$truc\n";
print { $handle_entrees_sorties[$i] } "$truc\n";

Si HANDLE_FICHIER est une variable et que le token suivant est un terme, elle peut être prise à tort pour un opérateur à moins que vous n'interposiez un + ou ne mettiez des parenthèses autour des arguments. Par exemple :

 
Sélectionnez
print $a - 2;   # envoie $a - 2 sur le handle par défaut (en général STDOUT)
print $a (- 2); # envoie -2 sur le handle de fichier spécifié par $a
print $a -2;    # idem (règles d'analyse bizarres :-)

Si HANDLE_FICHIER est omis, la fonction affiche sur le handle de fichier de sortie actuellement sélectionné, initialement STDOUT. Pour mettre le handle de fichier de sortie par défaut à autre chose que STDOUT, utilisez l'opération select HANDLE_FICHIER.(206) Si LISTE est également omise, la fonction affiche $_. Comme print prend une LISTE en argument, tout élément de cette LISTE est évalué dans un contexte de liste. Ainsi quand vous écrivez :

 
Sélectionnez
print SORTIE <STDIN>;

ce n'est pas la ligne suivante de l'entrée standard qui va être affichée, mais toutes les lignes de l'entrée standard jusqu'à la fin du fichier, puisque c'est ce que <STDIN> renvoie dans un contexte de liste. Si vous voulez autre chose, écrivez :

 
Sélectionnez
print SORTIE scalar <STDIN>;

De même, en se souvenant de la règle si-ça-ressemble-à-une-fonction-c'est-une-fonction, faites attention à ne pas faire suivre le mot-clé print d'une parenthèse gauche à moins que la parenthèse droite correspondante ne termine les arguments du print-interposez un + ou mettez des parenthèses à tous les arguments :

 
Sélectionnez
print (1+2)*3, "\n";   # mauvais
print +(1+2)*3, "\n";  # ok
print ((1+2)*3, "\n"); # ok

printf Image non disponible Image non disponible Image non disponible

 
Sélectionnez
printf HANDLE_FICHIER FORMAT, LISTE
printf FORMAT, LISTE

Cette fonction affiche une chaîne formatée sur HANDLE_FICHIER ou, s'il est omis, sur le handle de fichier de sortie courant, initialement STDOUT. Le premier élément de LISTE doit être une chaîne qui indique comme formater les éléments suivants. La fonction est similaire à printf (3) et fprintf (3). La fonction est exactement équivalente à :

 
Sélectionnez
print HANDLE_FICHIER sprintf FORMAT, LISTE

sauf que $\ ($OUTPUT_RECORD_SEPARATOR) n'est pas ajouté à la fin. Si use locale est actif, le caractère utilisé comme séparateur de la partie décimale dans les nombres à virgule flottante est affecté par la locale LC_NUMERIC.

Une exception n'est levée que si un type de référence invalide est employé pour l'argument HANDLE_FICHIER. Les formats inconnus sont sautés sans modification. Ces deux situations déclenchent des avertissements si ceux-ci sont activés.

Voir les fonctions print et sprintf ailleurs dans ce chapitre. La description de sprintf inclut la liste des spécifications des formats. Nous l'aurions volontiers reproduite ici, mais ce livre est d'ores et déjà un désastre écologique.

Si vous omettez à la fois le FORMAT et la LISTE, $_ est utilisé — mais dans ce cas, vous auriez dû utiliser print. Ne tombez pas dans le piège d'utiliser un printf lorsqu'un simple print aurait très bien fait l'affaire. La fonction print est bien plus efficace et bien moins sujette à erreurs.

prototype Image non disponible

 
Sélectionnez
prototype FONCTION

Renvoie le prototype d'une fonction dans une chaîne (ou undef si la fonction n'a pas de prototype). FONCTION est une référence vers, ou le nom de, la fonction pour laquelle vous désirez trouver le prototype.

Si FONCTION est une chaîne commençant par CORE::, la suite est prise en tant que nom pour les fonctions internes de Perl, et une exception est levée s'il n'existe pas de telle fonction interne. Si la fonction interne n'est pas surchargeable (comme qw//) ou si ses arguments ne peuvent pas être exprimés par un prototype (comme system), la fonction renvoie, undef car la fonction interne ne se comporte pas véritablement comme une fonction Perl. Sinon, la chaîne décrivant le prototype équivalent est renvoyée.

push

 
Sélectionnez
push TABLEAU
push

Cette fonction traite TABLEAU comme une pile et empile les valeurs de LISTE à la fin du tableau. La taille de TABLEAU est allongée de la longueur de LISTE. La fonction renvoie cette nouvelle taille. La fonction push entraîne les mêmes effets que :

 
Sélectionnez
foreach $valeur (fonction_liste()) {
    $tableau[++$#tableau] = $valeur;
}

ou que :

 
Sélectionnez
splice @tableau, @tableau, 0, fonction_liste();

mais est beaucoup plus performante (à la fois pour vous et pour votre ordinateur). Vous pouvez utilisez push associée avec shift pour construire une file ou un registre à décalage assez efficace :

 
Sélectionnez
for (;;) {
    push @tableau, shift @tableau;
    ...
}

Voir également pop et unshift.

q/CHAINE/

 
Sélectionnez
q/CHAINE/
qq/CHAINE/
qr/CHAINE/
qw/CHAINE/
qx/CHAINE/

Protections généralisées. Voir la section Choisissez vos délimiteurs au chapitre 2. Pour les annotations de statut pour qx//, voir readpipe. Pour les annotations de statut pour qr//, voir m//. Voir également Garder le contrôle au chapitre 5.

quotemeta Image non disponible

 
Sélectionnez
quotemeta EXPR
quotemeta

Cette fonction renvoie la valeur de EXPR avec tous les caractères non alphanumériques précédés d'un backslash (\). (C'est-à-dire que tous les caractères ne correspondant pas à /[A-Za-z_0-9]/ seront précédés d'un backslash dans la chaîne renvoyée, sans tenir compte des valeurs des locales.) Il s'agit de la fonction interne implémentant l'échappement \Q dans les contextes d'interpolation (comprenant les chaînes entre guillemets, entre apostrophes inverses ou les motifs).

rand

 
Sélectionnez
rand EXPR
rand

Cette fonction renvoie un nombre à virgule flottante pseudoaléatoire supérieur ou égal à 0 et inférieur à la valeur de EXPR.(EXPR doit être positif.) Si EXPR est omise, la fonction renvoie un nombre à virgule flottante entre 0 et 1 (comprenant 0, mais excluant 1). rand appelle automatiquement srand sauf si la fonction srand a déjà été appelée. Voir également srand.

Pour obtenir une valeur entière, comme pour un lancer de dé, combinez ceci avec int, comme dans :

 
Sélectionnez
$lancer = int(rand 6) +1;   # $lancer est maintenant un entier
                            # compris entre 1 et 6

Comme Perl utilise la fonction pseudoaléatoire de votre propre bibliothèque C, comme random(3) ou drand48(3), la qualité de la distribution n'est pas garantie. Si vous avez besoin d'aléatoire plus fort, comme pour de la cryptographie, vous devriez plutôt consulter la documentation de random(4) (si votre système possède un périphérique /dev/random ou /dev/urandom), le module Math::TrulyRandom de CPAN, ou un bon bouquin sur la génération de nombres pseudoaléatoires en informatique, comme le second volume de Knuth.(207)

read Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
read HANDLE_FICHIER, SCALAIRE, LONGUEUR, DECALAGE
read HANDLE_FICHIER, SCALAIRE, LONGUEUR

Cette fonction essaye de lire LONGUEUR octets de données dans la variable SCALAIRE depuis le HANDLE_FICHIER spécifié. La fonction renvoie le nombre d'octets réellement lus ou 0 en fin de fichier. undef est renvoyée en cas d'erreur. SCALAIRE est ajusté à la taille réellement lue. Le DECALAGE, s'il est spécifié, indique l'endroit de la variable à partie duquel commencer à écrire des octets, vous pouvez ainsi lire au milieu d'une chaîne.

Pour copier des données du handle de fichier DEPUIS dans le handle VERS, vous pouvez écrire :

 
Sélectionnez
while (read DEPUIS, $tampon, 16384) {
    print VERS $tampon;
}

L'inverse d'un read est simplement print, qui connaît déjà la longueur de la chaîne à écrire, et qui peut écrire une chaîne de n'importe quelle longueur. Ne faites pas l'erreur d'employer write, qui est uniquement utilisé dans les formats.

La fonction read de Perl est en fait implémentée par la fonction d'entrée/sortie standard fread(3), ce qui fait que le véritable appel système read(2) peut lire plus que LONGUEUR octets pour remplir le tampon d'entrée et que fread(3) peut faire plus d'un appel système à read(2) pour remplir ce tampon. Vous pouvez spécifier l'appel système réel par sysread pour mieux contrôler les entrées/sorties. Les appels à read et à sysread ne doivent pas être mélangés à moins d'être adepte des sciences occultes (ou des soirées cuir et chaînes). Quelle que soit celle que vous employez, faites attention : lorsque vous lisez depuis un fichier contenant un encodage Unicode ou n'importe quel encodage sur plusieurs octets, les limites du tampon peuvent tomber au milieu d'un caractère.

readdir Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
readdir HANDLE_REPERTOIRE

Cette fonction lit les entrées de répertoire (qui ne sont que de simples noms de fichiers) depuis un handle de répertoire ouvert par opendir. Dans un contexte scalaire, cette fonction renvoie l'entrée de répertoire suivante si elle existe, undef sinon. Dans un contexte de liste, elle renvoie le reste des entrées du répertoire, ce qui donnera bien sûr une liste nulle s'il n'y en a plus. Par exemple :

 
Sélectionnez
opendir(CE_REP, "." or die "sérieusement endommagé : $!";
@tous_les_fichiers = readdir CE_REP;
closedir CE_REP;
print "@tous_les_fichiers\n";

Ceci affiche tous les fichiers du répertoire courant sur une seule ligne. Pour éviter les entrées . et .., employez l'une de ces incantations (quelle que soit celle à laquelle vous pensez, elle sera moins illisible) :

 
Sélectionnez
@tous_les_fichiers = grep { $_ ne '.' and $_ ne '..' } readdir CE_REP;
@tous_les_fichiers = grep { not /^[.][.]?\z/ } readdir CE_REP;
@tous_les_fichiers = grep { not /^\.{1,2}\z/ } readdir CE_REP;
@tous_les_fichiers = grep !/^\.\.?\z/, readdir CE_REP;

Et pour éviter tous les fichiers .*, écrivez ceci :

 
Sélectionnez
@tous_les_fichiers = grep !/^\./, readdir CE_REP;

Pour ne lister que les fichiers texte, écrivez :

 
Sélectionnez
@fichiers_texte = grep -T, readdir CE_REP;

Mais attention à ce dernier exemple, car le répertoire doit être recollé au résultat de readdir si ce n'est pas le répertoire courant — comme ceci :

 
Sélectionnez
opendir(CE_REP, $chemin); or die "opendir $chemin impossible : $!" ;
@fichiers_points = grep { /^\./ && -f } map { "$chemin/$_" }
readdir(CE_REP);
closedir CE_REP;

readline Image non disponible Image non disponible Image non disponible

 
Sélectionnez
readline HANDLE_FICHIER

Il s'agit de la fonction interne implémentant l'opérateur <HANDLE_FICHIER>, mais vous pouvez l'utiliser directement. La fonction lit l'enregistrement suivant depuis HANDLE_FICHIER, qui peut être un nom de handle de fichier ou une expression de handle de fichier indirect renvoyant soit le nom d'un véritable handle de fichier, soit une référence à quoi que ce soit ressemblant à une objet handle de fichier, comme un typeglob. (Les versions de Perl antérieures à la 5.6 acceptent seulement un typeglob.) Dans un contexte scalaire, chaque appel lit et renvoie le prochain enregistrement jusqu'à ce que l'on atteigne la fin de fichier, avec laquelle l'appel suivant renvoie undef. Dans un contexte de liste, readline lit tous les enregistrements jusqu'à atteindre la fin de fichier et renvoie alors une liste d'enregistrements. Par « enregistrements », il faut normalement entendre une ligne de texte, mais si la variable spéciale $/ ($INPUT_RECORD_SEPARATOR) est différente de sa valeur par défaut, l'opérateur « avalera » le texte différemment. De même, certaines disciplines en entrée, comme :para (mode paragraphe) renverront des enregistrements par morceaux, autres que des lignes. Le positionnement de la discipline :slurp (ou $/ = undef) entraînera l'avalement du fichier entier.

Lorsqu'on avale des fichiers tout rond dans un contexte scalaire, s'il vous arrive de gober un fichier vide, readline renvoie "" la première fois et undef toutes les fois suivantes. Si l'on avale tout rond en partant du handle de fichier magique ARGV, chaque fichier renvoie une seule bouchée (encore une fois, les fichiers vides renvoient ""), suivi par un seul undef lorsque tous les fichiers on été digérés.

De plus amples détails sur l'opérateur <HANDLE_FICHIER> sont donnés dans la section Opérateurs d'entrée au chapitre 2.

 
Sélectionnez
$ligne = <STDIN>;
$ligne = readline(STDIN);       # idem
$ligne = readline(*STDIN);      # idem
$ligne = readline(\*STDIN);     # idem

open my $hf, "<&=STDIN" or die;
bless $hf => 'UneVieilleClasse';
$ligne = readline($hf);         # idem

readlink Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
readlink EXPR
readlink

Cette fonction renvoie le nom d'un fichier pointé par un lien symbolique. EXPR doit donner le nom d'un fichier dont la dernière composante est un lien symbolique. S'il ne s'agit pas d'un lien symbolique, ou si les liens symboliques ne sont pas implémentés dans le système de fichier, ou encore si une erreur se produit, la fonction renvoie la undef et vous devrez vérifier le code d'erreur dans $!.

Prenez garde, car le lien symbolique renvoyé peut être relatif à l'endroit spécifié. Par exemple, vous pouvez écrire :

 
Sélectionnez
readlink "/usr/local/src/exprimez/vous.h"

et readlink pourrait renvoyer :

 
Sélectionnez
../exprimez.1.23/includes/vous.h

ce qui n'est pas franchement utile à moins que le répertoire courant ne soit justement /usr/local/src/exprimez.

readpipe Image non disponible Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
readpipe scalar EXPR
readpipe LIST (à l'étude)

Il s'agit de la fonction interne implémentant la construction protégée qx// (connue également en tant qu'opérateur apostrophes inverses). Elle est parfois commode lorsque vous avez besoin de spécifier votre EXPR d'une manière qui ne serait pas pratique avec les apostrophes. Prenez garde, car nous pourrions modifier à l'avenir cette interface pour supporter un argument LISTE qui la ferait plus ressembler à la fonction exec, n'imaginez donc pas qu'elle continuera à fournir un contexte scalaire pour EXPR. Indiquez vous-même scalar ou utilisez la forme avec LISTE. Qui sait, peut-être cela fonctionnera-t-il au moment où vous lirez ceci.

recv Image non disponible Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
recv SOCKET, SCALAIRE, LONGUEUR, FLAGS

Cette fonction reçoit un message sur une socket. Elle s'attend à recevoir LONGUEUR octets de données dans la variable SCALAIRE depuis le handle de fichier SOCKET. La fonction renvoie l'adresse de l'expéditeur, ou undef s'il y a une erreur. SCALAIRE est ajusté à la longueur effectivement lue. Les FLAGS de la fonction sont les mêmes que ceux de recv(2). Voir la section Sockets au chapitre 16.

redo Image non disponible

 
Sélectionnez
redo ETIQUETTE
redo

L'opérateur redo recommence le bloc d'une boucle sans réévaluer la condition. Le bloc continue, s'il existe, n'est pas exécuté. Si l'ETIQUETTE est omise, l'opérateur se réfère à la boucle la plus interne l'encadrant. Cet opérateur est normalement utilisé par les programmes qui souhaitent dissimuler à eux-mêmes ce qui vient d'être entré :

 
Sélectionnez
# Une boucle qui joint les lignes coupées par un antislash.
while (<STDIN>) {
    if (s/\\\n$// && defined($ligne_suivante = <STDIN>)) {
        $_ .= $ligne_suivante;
        redo LIGNE;
    }
    print; # ou ce que vous voulez
}

On ne peut pas utiliser redo pour sortir d'un bloc qui renvoie une valeur comme eval {}, sub {} ou do {}, ni d'une opération grep ou map. Si les avertissements sont actifs, Perl vous avertira si vous faites un redo dans une boucle qui ne se trouve pas dans votre portée lexicale courante.

Un bloc en soi-même est sémantiquement identique à une boucle qui ne s'exécute qu'une seule fois. Ainsi redo à l'intérieur un tel bloc le changera en une construction de boucle. Voir la section Contrôle de boucle au chapitre 4.

ref Image non disponible

 
Sélectionnez
ref EXPR
ref

L'opérateur ref renvoie une valeur vraie si EXPR est une référence, sinon faux. La valeur renvoyée dépend du type d'objet auquel il est fait référence. Les types intégrés comprennent :

 
Sélectionnez
SCALAR
ARRAY
HASH
CODE
GLOB
REF
LVALUE
IO::Handle

Si l'objet référencé a été consacré (avec bless) dans un paquetage, c'est le nom du paquetage qui est renvoyé. Vous pouvez voir ref comme une sorte d'opérateur « typeof ».

 
Sélectionnez
if (ref($r) eq "HASH") {
    print "r est une référence à un hachage.\n";
} elsif (ref($r) eq "Bosse") {   # Vilain, voir ci-dessous.
    print "r est une référence à un objet Bosse.\n";
} elsif (not ref ($r)) {
    print "r n'est pas du tout une référence.\n";
}

On considère que tester l'égalité de votre classe d'objet avec une classe particulière est une erreur de style OO (orienté objet), puisqu'une classe dérivée aura un nom différent, mais devra permettre l'accès aux méthodes de la classe de base. Il vaut mieux utiliser la méthode isa de la classe UNIVERSAL comme ceci :

 
Sélectionnez
if ($r->isa("Bosse")) {
    print "r est une référence à un objet Bosse, ou à une sous-classe.\n";
}

Il vaut mieux normalement ne rien tester du tout, puisque le mécanisme OO n'enverra pas l'objet à votre méthode sauf s'il pense qu'elle est la plus appropriée. Voir les chapitres 8 et 12 pour plus de détails. Voir aussi la fonction reftype dans le pragma use attributes au chapitre 31.

rename Image non disponible

 
Sélectionnez
rename ANCIEN_NOM, NOUVEAU_NOM

Cette fonction change le nom d'un fichier. Elle renvoie vrai en cas de succès et faux sinon. Elle ne fonctionnera pas (normalement) à travers les frontières des systèmes de fichiers, bien que sur un système Unix, la commande mv puisse parfois être utilisée pour compenser cela. Si un fichier nommé NOUVEAU_NOM existe déjà, il sera détruit. Les systèmes non Unix peuvent comporter des restrictions supplémentaires.

Voire le module standard File::Copy pour renommer les fichiers d'un système de fichiers à l'autre.

require Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
require VERSION
require EXPR
require

Cette fonction exprime une sorte de dépendance envers son argument.

Si l'argument est une chaîne, require charge et exécute le code Perl trouvé dans le fichier séparé dont le nom est donné par la chaîne. Ceci est similaire à l'exécution d'un do, mis à part que require vérifie si le fichier de bibliothèque a déjà été chargé et lève une exception si un quelconque problème est rencontré. (On peut donc l'utiliser pour exprimer des dépendances de fichiers sans se soucier d'une duplication de la compilation.) Comme ses cousines do et use, require sait comment rechercher le chemin d'inclusion, stocké dans le tableau @INC et sait également mettre à jour %INC en cas de succès. Voir le chapitre 28.

Le fichier doit renvoyer vrai comme dernière valeur pour indiquer l'exécution réussie du code d'initialisation, il est donc habituel de terminer ce genre de fichier par un 1;, à moins que vous ne soyez sûrs qu'il renverra vrai de toute façon.

Si l'argument de require est un numéro de version de la forme 5.6.2, require exige que la version de Perl en train d'être exécuté soit égale ou supérieure à ce numéro de version. (Perl accepte également un nombre à virgule flottante comme 5.005_03 pour une compatibilité avec les anciennes versions de Perl, mais cette forme est maintenant fortement déconseillée, car les foules venant d'autres cultures ne la comprennent pas.) Ainsi, un script qui requiert Perl version 5.6 peut commencer par :

 
Sélectionnez
require 5.6.0           # ou require v5.6.0

et les versions plus anciennes de Perl échoueront. Cependant, comme tous les require, la vérification est réalisée lors de l'exécution. Vous pouvez préférer écrire use 5.6.0 pour un test à la compilation. Voir aussi $PERL_VERSION au chapitre 28.

Si l'argument de require est le nom dénudé d'un paquetage (voir package), require suppose que le suffixe est automatiquement .pm, facilitant ainsi le chargement de modules standard. Cela ressemble à use, mis à part le fait que cela se produit à l'exécution et non à la compilation et que la méthode d'import n'est pas appelée. Par exemple, pour charger Socket.pm sans introduire aucun symbole dans le package courant, écrivez ceci :

 
Sélectionnez
require Socket;         # au lieu de "use Socket;"

Mais on peut toutefois obtenir le même effet avec ce qui suit, qui procure l'avantage de donner des avertissements à la compilation si Socket.pm ne peut être trouvé :

 
Sélectionnez
use Socket ();

L'utilisation de require sur un nom dénudé de paquetage remplace également tout :: dans le nom d'un paquetage par le séparateur de répertoires de votre système, généralement /. En d'autres termes, si vous essayez ceci :

 
Sélectionnez
require Machin::Truc;   # un formidable nom dénudé

la fonction require cherchera le fichier Machin/Truc.pm dans les répertoires spécifiés par le tableau @INC. Mais si vous essayez cela :

 
Sélectionnez
$classe = 'Machin::Truc';
require $classe;        # $classe n'est pas un nom dénudé

ou encore cela :

 
Sélectionnez
require "Machin::Truc"; # un littéral entre guillemets n'est pas un
                        #nom dénudé

la fonction require recherchera le fichier Machin::Truc dans le tableau @INC et se plaindra de ne pas y trouver Machin::Truc. Si cela arrive, vous pouvez faire ceci :

 
Sélectionnez
eval "require $classe";

Voir également les commandes do FICHIER, use, le pragma use lib et le module standard FindBin.

reset

 
Sélectionnez
reset EXPR
reset

On use (ou on abuse) de cette fonction généralement au début d'une boucle ou dans un bloc continue à la fin d'une boucle, pour nettoyer les variables globales ou réinitialiser les recherches ?? pour qu'elles puissent à nouveau fonctionner. L'EXPR est interprétée comme une liste de caractères uniques (les tirets sont autorisés pour les intervalles). Toutes les variables scalaires et tous les tableaux et hachages commençant par l'une de ces lettres sont remises dans leur état d'origine. Si l'EXPR est omise, les recherches de correspondance unique (?MOTIF?) sont réinitialisées pour correspondre à nouveau. La fonction réinitialise les variables ou les recherches uniquement pour le package courant. Elle renvoie toujours vrai. Pour réinitialiser toutes les variables en « X » , écrivez ceci :

 
Sélectionnez
reset 'X';

Pour réinitialiser toutes les variables en minuscules, écrivez cela :

 
Sélectionnez
reset 'a-z';

Enfin, pour ne réinitialiser que les recherches en ??, écrivez :

 
Sélectionnez
reset;

La réinitialisation de « A-Z » dans le package principal main n'est pas recommandée, car les tableaux et hachages ARGV, INC, ENV et SIG seront probablement balayés.

Les variables lexicales (créées par my) ne sont pas affectées. L'emploi de reset est vaguement déprécié, car il efface un peu trop facilement des espaces de noms entiers et parce que l'opérateur ?? est lui-même vaguement déprécié.

Voir également la fonction delete_package() du module standard Symbol et la discussion entière sur les compartiments sécurisés dans la section Compartiments sécurisés au chapitre 23.

return Image non disponible

 
Sélectionnez
return EXPR
return

Cet opérateur entraîne le retour immédiat de la sous-routine courante (ou de l'eval ou du do FICHIER) avec la valeur spécifiée. Toute tentative d'utiliser return en dehors de ces trois endroits lève une exception. Remarquez également qu'un eval ne peut pas faire un return pour le compte de la sous-routine qui a appelé l'eval.

EXPR peut être évaluée dans un contexte de liste, scalaire ou vide, selon la manière dont la valeur de retour sera utilisé, ce qui peut varier d'une exécution à l'autre. C'est-à-dire que l'expression fournie sera évaluée dans le contexte de l'invocation du sous-programme. Si le sous-programme a été appelé dans un contexte scalaire, EXPR est également évaluée dans un contexte scalaire. Si le sous-programme a été appelé dans un contexte de liste, EXPR est également évaluée dans un contexte de liste. Un return sans argument renvoie la valeur scalaire undef dans un contexte scalaire et une liste vide () dans un contexte de liste, et (naturellement) rien du tout dans un contexte vide. Le contexte de l'appel au sous-programme peut être déterminé de l'intérieur du sous-programme par la fonction (mal nommée) wantarray.

reverse

 
Sélectionnez
reverse LISTE

Dans un contexte de liste, cette fonction renvoie une valeur liste composée des éléments de LISTE dans l'ordre inverse. La fonction peut être utilisée pour créer des séquences décroissantes :

 
Sélectionnez
for (reverse 1 .. 10) { ... }

Comme les hachages se transforment en listes quand ils sont passés en tant que LISTE, reverse peut également être employée pour inverser un hachage, à supposer que les valeurs soient uniques :

 
Sélectionnez
%machintruc = reverse %trucmachin;

Dans un contexte scalaire, la fonction concatène tous les caractères de LISTE et renvoie alors l'inverse, caractère par caractère, de la chaîne résultante.

Petite astuce : l'inversion d'une liste triée par une fonction définie par l'utilisateur peut parfois être plus facilement accomplie en triant d'abord la liste dans le sens opposé.

rewinddir Image non disponible Image non disponible Image non disponible

 
Sélectionnez
rewinddir HANDLE_REPERTOIRE

Cette fonction se positionne au début du répertoire pour la routine readdir sur HANDLE_REPERTOIRE. La fonction peut ne pas être disponible sur toutes les machines supportant readdirrewindir meurt si elle n'est pas implémentée. Elle renvoie vrai en cas de succès, faux sinon.

rindex

 
Sélectionnez
rindex CHAINE, SOUS_CHAINE, POSITION
rindex CHAINE, SOUS_CHAINE

Cette fonction agit exactement comme index mis à part le fait qu'elle renvoie la position de la dernière occurrence de SOUS_CHAINE dans CHAINE (un index inverse). La fonction renvoie $[-1 si aucune SOUS_CHAINE n'a été trouvée. Comme $[ est le plus souvent à 0 de nos jours, la fonction renvoie presque toujours -1. POSITION, si elle est spécifiée, est la position la plus à droite qui puisse être renvoyée. Pour scruter une chaîne à l'envers, écrivez :

 
Sélectionnez
$pos = length $chaine;
while (($pos = rindex $chaine, $a_chercher, $pos) >= 0) {
    print "Trouvé en $pos\n";
    $pos--;
}

rmdir Image non disponible Image non disponible Image non disponible

 
Sélectionnez
rmdir REPERTOIRE
rmdir

Cette fonction supprime le répertoire spécifié par REPERTOIRE si ce répertoire est vide. Si la fonction réussit, elle renvoie vrai ; sinon, elle renvoie faux. Voir également le module File::Path si vous voulez d'abord supprimer le contenu du répertoire et si vous n'envisagez pas d'appeler le shell avec rm -r, pour une raison ou une autre. (Si par exemple vous ne disposez pas de shell ou de commande rm, parce que vous n'avez pas encore PPT(208))

s/// Image non disponible Image non disponible Image non disponible

 
Sélectionnez
s///

L'opérateur de substitution. Voir la section Opérateurs de correspondance de motif au chapitre 5.

scalar

 
Sélectionnez
scalar EXPR

Cette pseudofonction peut être utilisée dans une LISTE pour forcer EXPR à être évaluée dans un contexte scalaire quand l'évaluation dans un contexte de tableau produirait un résultat différent. Par exemple :

 
Sélectionnez
my ($var_suivante) = scalar <STDIN>;

empêche <STDIN> de lire toutes les lignes depuis l'entrée standard avant d'effectuer l'affectation, puisqu'une affectation à une liste (même à une my liste) donne un contexte de liste. (Sans l'utilisation de scalar dans cet exemple, la première ligne de <STDIN> serait toujours assignée à $var_suivante, mais les lignes suivantes seraient lues et poubellisées, puisque la liste à laquelle nous sommes en train d'assigner ne peut recevoir qu'une seule valeur scalaire.)

Bien sûr, il serait plus simple et moins encombrant d'enlever les parenthèses, transformant ainsi le contexte de liste en un contexte scalaire :

 
Sélectionnez
my $var_suivante = <STDIN>;

Puisqu'une fonction print est un opérateur de LISTE, il vous faudrait écrire :

 
Sélectionnez
print "La longueur est ", scalar(@TABLEAU), "\n";

pour afficher la longueur de @TABLEAU.

Il n'existe aucune fonction « list » correspondant à scalar, puisqu'en pratique, on n'a jamais besoin de forcer l'évaluation dans un contexte de liste. Car toute opération demandant une LISTE fournit déjà un contexte de liste à ses arguments de liste, et ceci gratuitement.

Comme scalar est un opérateur unaire, si vous utilisez accidentellement une liste entre parenthèses pour l'EXPR, cette dernière se comportera comme une expression scalaire avec des virgules, en évaluant tous les éléments sauf le dernier dans un contexte vide et renvoyant l'élément final évalué dans un contexte scalaire. C'est rarement ce que vous voulez. La seule instruction suivante :

 
Sélectionnez
print uc(scalar(&machin,$truc)),$bidule;

est l'équivalent (im)moral de ces deux instructions :

 
Sélectionnez
&machin; print(uc($truc),$bidule);

Voir le chapitre 2 pour plus de détails sur le séparateur virgule. Voir la section Prototypes au chapitre 6 pour plus d'informations sur les opérateurs unaires.

seek Image non disponible Image non disponible

 
Sélectionnez
seek HANDLE_FICHIER, DECALAGE, DEPART

Cette fonction positionne le pointeur de fichier pour HANDLE_FICHIER, exactement comme l'appel d'entrée/sortie standard fseek(3). La première position dans un fichier correspond à un décalage de 0, et non de 1. Les décalages se réfèrent à des positions en octets, et non des numéros de ligne. En général, comme les longueurs de ligne varient, il n'est pas possible d'accéder à un numéro de ligne précis sans lire tout le fichier jusqu'à cet endroit, à moins que toutes vos lignes ne soient d'une longueur fixe ou que vous ayez construit un index convertissant les numéros de lignes en décalages d'octets. (Les mêmes restrictions s'appliquent aux positions des caractères dans un fichier avec des encodages de caractères de longueur variable : le système d'exploitation ne sait pas ce que sont les caractères, il ne connaît que des octets.)

HANDLE_FICHIER peut être une expression dont la valeur donne un véritable nom de handle de fichier ou une référence vers quoi que ce soit ressemblant à un objet handle de fichier. La fonction renvoie vrai en cas de succès, faux sinon. Pour des raisons pratiques, la fonction peut calculer pour vous des décalages depuis diverses positions dans le fichier. La valeur de DEPART indique la position à partir de laquelle votre DECALAGE commencera : 0, pour le début du fichier ; 1, pour la position courante dans le fichier ; ou 2, pour la fin du fichier. Le DECALAGE peut être négatif pour un DEPART de 1 ou de 2. Si vous désirez employer des valeurs symboliques pour DEPART, vous pouvez utiliser SEEK_SET, SEEK_CUR et SEEK_END importée depuis les modules IO::Seekable ou POSIX, ou depuis la version 5.6 de Perl, depuis le module Fcntl.

Si vous voulez connaître la position dans le fichier pour sysread ou syswrite, n'employez pas seek ; les conséquences des tampons des entrées/sorties standards rendent la position système dans un fichier imprévisible et non portable. Utilisez sysseek à la place.

À cause des règles rigoureuses du C ANSI, vous devez sur certains systèmes faire un seek à chaque fois que vous basculez entre une lecture et une écriture. Parmi d'autres effets, ceci peut avoir comme conséquence d'appeler la fonction clearerr(3) de la bibliothèque standard d'entrée/sortie. Un DEPART de 1 (SEEK_CUR) avec un DECALAGE de 0 est utile pour ne pas bouger de la position courante dans le fichier :

 
Sélectionnez
seek(TEST,0,1);

Cette fonction s'avère intéressante notamment pour suivre la croissance d'un fichier, comme ceci :

 
Sélectionnez
for (;;) {
    while (<JOURNAL>) {
        gnoquer($_)             # Traiter la ligne courante
    }
    sleep 15;
    seek LOG,0,1;               # RAZ erreur de fin de fichier
}

Le seek final réinitialise l'erreur de fin de fichier sans bouger le pointeur. Si cela ne fonctionne pas, selon l'implémentation de la bibliothèque C d'entrées/sorties standards, alors il vous faut plutôt ce genre de code :

 
Sélectionnez
for (;;) {
    for ($pos_cour = tell FILE; <FILE>; $pos_cour = tell FILE) {
        gnoquer($_)             # Traiter la ligne courante
    }
    sleep $un_moment;
    seek FILE, $pos_cour, 0;    # RAZ erreur de fin de fichier
}

Des stratégies similaires peuvent être employées pour conserver les adresses de seek pour chaque ligne dans tableau.

seekdir Image non disponible Image non disponible Image non disponible

 
Sélectionnez
seekdir HANDLE_REPERTOIRE, POSITION

Cette fonction fixe la position courante pour le prochain appel à readdir sur HANDLE_REPERTOIRE. POSITION doit être une valeur renvoyée par telldir. Cette fonction comporte les mêmes dangers relatifs à un possible compactage du répertoire que la routine de la bibliothèque système correspondante. La fonction peut ne pas être implémentée partout où l'est readdir. Elle ne l'est certainement pas si readdir est absente.

select (handle de fichier de sortie) Image non disponible

 
Sélectionnez
select HANDLE_FICHIER
select

Pour des raisons historiques, il existe deux opérateurs select totalement distincts l'un de l'autre. La section suivante décrit l'autre. Cette version de l'opérateur select renvoie le handle de fichier de sortie actuellement sélectionné et, si HANDLE_FICHIER est fourni, fixe le handle par défaut courant pour la sortie. Cela a deux conséquences : d'abord, un write ou un print sans handle de fichier s'adressera à ce handle par défaut. Ensuite, les variables spéciales relatives à la sortie se référeront à ce handle de fichier de sortie. Par exemple, s'il faut fixer un format d'en-tête identique pour plus d'un handle de fichier de sortie, il vous faudrait faire ceci :

 
Sélectionnez
select RAPPORT1;
$^ = 'mon_en_tete';
select RAPPORT2;
$^ = 'mon_en_tete';

Mais remarquez que cela laisse RAPPORT2 comme handle de fichier actuellement sélectionné. Ce qui est un comportement antisocial condamnable puisque cela peut réellement démolir les routines print ou write de quelqu'un d'autre. Les routines de bibliothèque bien écrites laissent le handle de fichier sélectionné courant dans l'état où elles l'ont trouvé en entrant. À cet effet, HANDLE_FICHIER peut être une expression dont la valeur donne le nom du véritable handle de fichier. Il vous est donc possible de sauvegarder et de restaurer le handle de fichier actuellement sélectionné :

 
Sélectionnez
my $ancien_hf = select STDERR; $| = 1; select $ancien_hf;

ou de manière idiomatique (mais nettement plus absconse) :

 
Sélectionnez
select((select(STDERR), $| = 1)[0])

Cet exemple fonctionne en construisant une liste composée de la valeur renvoyée par select(STDERR) (qui sélectionne STDERR par effet de bord) et $| = 1 (qui est toujours 1), mais vide le tampon de STDERR, maintenant sélectionné, par effet de bord. Le premier élément de cette liste (le handle de fichier précédemment sélectionné) est maintenant utilisé comme un argument vers le select extérieur. Étrange, n'est-ce pas ? C'est ce que vous obtenez quand vous connaissez juste assez de Lisp pour être dangereux.

Vous pouvez également utiliser le module standard SelectSaver pour restaurer automatiquement le select précédent à la sortie de la portée.

Maintenant que nous avons expliqué tout cela, nous devons souligner que vous n'aurez que rarement besoin d'utiliser cette forme de select, car la plupart des variables spéciales auxquelles vous pouvez vouloir accéder possèdent des méthodes d'enrobage orientées objet. Donc, au lieu d'accéder directement à $|, vous pouvez écrire :

 
Sélectionnez
use IO::Handle;  # Malheureusement, ce *n'est pas* un petit module
STDOUT->autoflush(1);

Et l'exemple précédent de format peut être codé comme suit :

 
Sélectionnez
use IO::Handle;
RAPPORT1->format_top_name("mon_en_tete");
RAPPORT2->format_top_name("mon_en_tete");

select (descripteurs de fichiers prêts) Image non disponible Image non disponible

 
Sélectionnez
select BITS_LEC, BITS_ECR, BITS_ERR, MINUTEUR

La forme à quatre arguments de select est totalement indépendante de l'opérateur select précédemment décrit. Celui-ci sert à découvrir lesquels (s'il en existe) de vos descripteurs de fichiers sont prêts à effectuer une entrée ou une sortie, ou à informer d'une condition d'exception. (Ce qui vous évite une scrutation.) Elle appelle l'appel système select(2) avec les masques de bits que vous avez spécifiés, qui peuvent être construits grâce à fileno et vec, comme ceci :

 
Sélectionnez
$lec_entree = $ecr_entree = $err_entree = ";
vec($lec_entree, fileno(STDIN), 1) = 1;
vec($ecr_entree, fileno(STDOUT), 1) = 1;
$err_entree = $lec_entree | $ecr_entree;

Si vous voulez faire un select sur plusieurs handles de fichier, il peut être préférable d'écrire une routine :

 
Sélectionnez
sub bits_hf {
    my @liste_hf = @_;
    my $bits;
    for (@liste_hf) {
        vec($bits, fileno($_), 1) = 1;
    }
    return $bits;
}
$lec_entree = bits_hf(qw(STDIN TTY MA_SOCK));

Si vous désirez utiliser les mêmes masques de bits de façon répétitive (et c'est plus efficace), la manière la plus courante est :

 
Sélectionnez
($nb_trouves, $temps_restant) =
    select( $lec_sortie=$lec_entree, $ecr_sortie=$ecr_entree,
            $err_sortie=$err_entree, $minuteur);

Ou pour bloquer jusqu'à ce qu'un descripteur de fichiers soit prêt :

 
Sélectionnez
$nb_trouves = select( $lec_sortie=$lec_entree, $ecr_sortie=$ecr_entree,
    $err_sortie=$err_entree, undef);

Comme vous pouvez le constater, l'appel de select dans un contexte scalaire renvoie seulement $nb_trouves, soit le nombre de descripteurs de fichiers prêts trouvés.

L'astuce $ecr_sortie=$ecr_entree fonctionne, car la valeur d'une affectation est le côté gauche, ce qui fait que $ecr_sortie est d'abord modifié par l'affectation, puis par le select, alors que $ecr_entree reste inchangé.

Chaque argument peut également valoir undef. Le MINUTEUR, s'il est spécifié, est en secondes(209), et peut éventuellement comporter une virgule. (Un délai de 0 effectue une scrutation.) Toutes les implémentations ne sont pas capables de renvoyer le $temps_restant. Dans ce cas, elles renverront toujours un $temps_restant égal au $minuteur fourni.

Le module standard IO::Select fournit une interface plus amicale à select, surtout parce qu'il effectue pour vous toutes les opérations sur les masques de bits.

Un des emplois possibles de select consiste à endormir un processus avec une résolution plus fine que ce qu'admet sleep, ceci en spécifiant undef pour tous les masques de bits. Ainsi pour vous endormir pendant (au moins) 4,75 secondes, utilisez :

 
Sélectionnez
select undef, undef, undef, 4.75;

(Le triple undef peut ne pas fonctionner sur certains systèmes non UNIX, et il vous faut alors mettre fallacieusement au moins un masque de bits à un descripteur de fichier qui ne sera jamais prêt.)

Il est dangereux de mélanger des entrées/sorties bufferisées (comme read ou <HANDLE>) avec select, à l'exception de ce que permet POSIX, et même dans ce cas, uniquement sur les systèmes réellement POSIX. Employez plutôt sysread.

semctl Image non disponible Image non disponible

 
Sélectionnez
semctl CLEF, NUM_SEM, CMD, ARG

Cette fonction invoque l'appel système semctl(2) des IPC System V. Vous devrez probablement d'abord faire use IPC::SysV pour obtenir les définitions de constantes correctes. Si CMD vaut IPC_STAT ou GETALL, ARG doit alors être une variable qui contiendra la structure semid_ds ou le tableau des valeurs de sémaphore qui sont renvoyés. Comme pour ioctl et fcntl, les valeurs renvoyées sont undef en cas d'erreur, « 0 but true » (N.d.T. : 0, mais vrai) pour zéro ou sinon la valeur réellement renvoyée.

Voir également le module IPC::Semaphore. Cette fonction n'est disponible que sur les systèmes supportant les IPC System V.

semget Image non disponible Image non disponible

 
Sélectionnez
semget CLEF, NB_SEM S, TAILLE, FLAGS

Cette fonction invoque l'appel système semget(2) des IPC System V. Vous devrez probablement d'abord faire use IPC::SysV pour obtenir les définitions de constantes correctes. La fonction renvoie l'ID du sémaphore ou undef en cas d'erreur.

Voir également le module IPC::Semaphore. Cette fonction n'est disponible que sur les systèmes supportant les IPC System V.

semop Image non disponible Image non disponible

 
Sélectionnez
semop CLEF, CHAINE_OP

Cette fonction invoque l'appel système semop(2) des IPC System V pour réaliser des opérations sur les sémaphores, comme signaler ou attendre la libération. Vous devrez probablement d'abord faire use IPC::SysV pour obtenir les définitions de constantes correctes.

CHAINE_OP doit être un tableau empaqueté de structures semop. Vous pouvez construire chaque structure semop en écrivant pack("s*", $num_sem, $op_sem, $flags_sem). Le nombre d'opérations de sémaphores est donné par la longueur de CHAINE_OP. La fonction renvoie vrai si elle a réussi, faux en cas d'erreur.

Le code qui suit attend sur le sémaphore $num_sem de l'ensemble de sémaphores identifié par $id_sem :

 
Sélectionnez
$op_sem = pack "s*", $semnum, -1, 0;
semop $id_sem, $op_sem or die "Problème de sémaphore : $!\n";

Pour envoyer un signal au sémaphore, il vous suffit de remplacer -1 par 1.

Voir également le module IPC::Semaphore. Cette fonction n'est disponible que sur les systèmes supportant les IPC System V.

send Image non disponible Image non disponible Image non disponible

 
Sélectionnez
send SOCKET, MSG, FLAGS, VERS
send SOCKET, MSG, FLAGS

Cette fonction envoie un message sur une socket. Elle prend les mêmes flags que l'appel système du même nom — voir send(2). Sur des sockets non connectées, vous devez spécifier une destination VERS laquelle envoyer les données, ce qui fait que le send de Perl fonctionne comme sendto(2). La fonction send renvoie le nombre d'octets envoyés, ou undef en cas d'erreur.

(Certains systèmes traitent improprement les sockets comme des objets différents de simples descripteurs de fichiers, ce qui vous oblige à toujours utiliser send et recv sur les sockets au lieu des opérateurs d'entrée/sortie standards.)

Une erreur qu'au moins l'un de nous fait fréquemment est de confondre le send de Perl avec le send de C en écrivant :

 
Sélectionnez
send SOCK, $tampon, $length $tampon # FAUX

Ceci échouera mystérieusement selon le rapport exigé par le système entre la longueur de la chaîne et les bits de FLAGS. Voir la section Passage de message au chapitre 16 pour plus d'exemples.

setpgrp Image non disponible Image non disponible Image non disponible

 
Sélectionnez
setpgrp PID, GRP_P

Cette fonction modifie le groupe de processus courant (GRP_P) pour le PID spécifié (employez un PID égal à 0 pour le processus courant). L'invocation de setpgrp lèvera une exception sur une machine n'implémentant pas setpgrp(2). Attention : certains systèmes ignoreront les arguments fournis et feront toujours setpgrp(0, $$). Ce sont heureusement les arguments que l'on fournit généralement. Si les arguments sont omis, ils vaudront 0,0 par défaut. La version BSD 4.2 de setpgrp n'acceptait aucun argument, mais pour BSD 4.4, c'est un synonyme de la fonction setpgid. Pour une meilleure portabilité (du moins théorique), utilisez directement la fonction setpgid du module POSIX. Ou, si vous voulez changer votre script en démon, la fonction POSIX::setsid() peut aussi bien faire l'affaire. Remarquez que la version POSIX de setpgrp n'accepte pas d'arguments, seul setpgrp(0,0) est donc portable.

setpriority Image non disponible Image non disponible Image non disponible

 
Sélectionnez
setpriority QUOI, QUI, PRIORITE

Cette fonction modifie la PRIORITE courante d'un processus, d'un groupe de processus ou d'un utilisateur, tel que spécifiés par QUOI et QUI. Voir setpriority(2). Son invocation lèvera une exception sur une machine où setpriority(2) n'est pas implémentée. Pour faire un nice sur votre processus de quatre unités vers le bas (la même chose que d'exécuter votre programme avec nice(1)), essayez :

 
Sélectionnez
setpriority 0, 0, getpriority(0, 0) + 4;

L'interprétation d'une priorité donnée peut varier d'un système d'exploitation à l'autre. Certaines priorités ne sont pas accessibles aux utilisateurs sans privilèges.

Voir également le module BSD::Resource de CPAN.

setsockopt Image non disponible Image non disponible Image non disponible

 
Sélectionnez
setsockopt SOCKET, NIVEAU, NOM_OPTION, VALEUR_OPTION

Cette fonction applique l'option de socket requise. La fonction renvoie undef en cas d'échec. NIVEAU spécifie quelle couche de protocole est visée par l'appel, ou SOL_SOCKET pour la socket elle-même qui se trouve au sommet de toutes les couches. VALEUR_OPTION peut être undef si vous ne voulez pas passer d'argument. Il est courant d'appliquer l'option SO_REUSEADDR, pour contourner le fait que l'on ne peut pas faire de bind vers une adresse donnée alors que la connexion TCP précédente sur ce port est toujours en train de se demander s'il faut en finir. Cela peut ressembler à ceci :

 
Sélectionnez
use Socket; socket(SOCK, ...)
    or die "Impossible de créer une socket : $!\n";
setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, 1)
    or warn "setsockopt impossible : $!\n";

Voir setsockopt(2) pour les autres valeurs possibles.

shift

 
Sélectionnez
shift TABLEAU
shift

Cette fonction enlève la première valeur du tableau et la renvoie, réduisant ainsi le tableau d'un élément et déplaçant toutes les autres d'une unité vers le bas. (Ou vers le haut, ou vers la gauche, selon votre vision du tableau. Nous aimons bien vers la gauche.) S'il n'y a pas d'éléments dans le tableau, la fonction renvoie undef.

Si TABLEAU est omis, la fonction décale @_ dans la portée lexicale des sous-programmes et des formats ; elle décale @ARGV dans les portées de fichiers (généralement, le programme principal) ou à l'intérieur de la portée lexicale établie par les constructions eval CHAINE, BEGIN {}, CHECK {}, INIT {} et END {}.

Les sous-programmes commencent souvent par recopier leurs arguments dans des variables lexicales et peuvent utiliser shift pour ce faire :(210)

 
Sélectionnez
sub marine {
    my $brasse   = shift;   # profondeur
    my $poissons = shift;   # nombre de poissons
    my $o2       = shift;   # concentration en oxygène
    # ...
}

shift est également employé pour traiter les arguments au début de votre programme :

 
Sélectionnez
while (defined($_ = shift)) {
    /^[^-]/   && do { unshift @ARGV, $_;   last };
    /^-w/     && do { $AVERTISSEMENTS = 1; next };
    /^-r/     && do { $RECURSION = 1;      last };
    die "Argument inconnu $_\n";
}

Vous pouvez également considérer les modules Getopt::Std et GetOpt::Long pour traiter les arguments de votre programme.

Voir également unshift, push, pop et splice. Les fonctions shift et unshift font la même chose à l'extrémité gauche d'un tableau que push et pop à l'extrémité droite.

shmctl Image non disponible Image non disponible

 
Sélectionnez
shmctl ID, CMD, ARG

Cette fonction invoque l'appel système shmctl(2) des IPC System V. Vous devrez probablement d'abord faire use IPC::SysV pour obtenir les définitions de constantes correctes.

Si CMD vaut IPC_STAT, ARG doit alors être une variable qui contiendra la structure shmid_ds renvoyée. Comme pour ioctl et fcntl, les valeurs renvoyées sont undef en cas d'erreur, « 0 but true » (N.d.T. : 0, mais vrai) pour zéro ou sinon la valeur réellement renvoyée.

Cette fonction n'est disponible que sur les systèmes supportant les IPC System V.

shmget Image non disponible Image non disponible

 
Sélectionnez
shmget CLEF, TAILLE, FLAGS

Cette fonction invoque l'appel système shmget(2) des IPC System V. La fonction renvoie l'ID du segment de mémoire partagée ou undef en cas d'erreur. Avant l'appel, faites use IPC::SysV.

Cette fonction n'est disponible que sur les systèmes supportant les IPC System V.

shmread Image non disponible Image non disponible

 
Sélectionnez
shmread ID, VAR, POS, TAILLE

Cette fonction lit depuis l'ID de segment de mémoire partagée en commençant à la position POS sur la longueur TAILLE (en s'y attachant, puis en copiant les données qui s'y trouvent et enfin en s'en détachant). VAR doit être une variable qui contiendra les données lues. La fonction renvoie vrai en cas de réussite et faux en cas d'erreur.

Cette fonction n'est disponible que sur les systèmes supportant les IPC System V.

shmwrite Image non disponible Image non disponible

 
Sélectionnez
shmwrite ID, CHAINE, POS, TAILLE

Cette fonction écrit sur l'ID de segment de mémoire partagée en commençant à la position POS sur la longueur TAILLE (en s'y attachant, puis en y copiant des données et enfin en s'en détachant). Si CHAINE est trop longue, seulement TAILLE octets seront utilisés ; si TAILLE est trop courte, des caractères nuls sont écrits pour remplir TAILLE octets. La fonction renvoie vrai en cas de réussite et faux en cas d'erreur.

Cette fonction n'est disponible que sur les systèmes supportant les IPC System V. (Vous êtes certainement fatigués de lire ceci — nous commençons à être fatigués de l'écrire.)

shutdown Image non disponible Image non disponible Image non disponible

 
Sélectionnez
shutdown SOCKET, COMMENT

Cette fonction arrête une connexion socket de la manière indiquée par COMMENT. Si COMMENT vaut 0, toute réception ultérieure est interdite. Si COMMENT vaut 1, toute émission ultérieure est interdite. Si COMMENT vaut 2, tout est interdit.

 
Sélectionnez
shutdown(SOCK, 0);    # plus de lectures
shutdown(SOCK, 1);    # plus d'écritures
shutdown(SOCK, 2);    # plus du tout d'entrées/sorties

Ceci est utile avec les sockets lorsque vous voulez prévenir l'autre côté que vous avez fini d'écrire, mais pas de lire, ou vice versa. C'est également une forme plus déterminée de fermeture, car elle empêche toute copie de ces descripteurs détenus par des processus forkés.

Imaginez un serveur qui veut lire la requête de son client jusqu'à la fin de fichier, puis envoyer une réponse. Si le client appelle close, cette socket n'est maintenant plus valide pour les entrées/sorties, aucune réponse ne pourra donc être renvoyée. À la place, le client doit utiliser shutdown pour fermer la moitié de la connexion :

 
Sélectionnez
print SERVEUR, "ma requete\n";  # envoi de données
shutdown(SERVEUR, 1);           # envoi de fin de ligne; plus d'écritures
$reponse = <SERVEUR>;           #, mais vous pouvez encore lire

(Si vous êtes arrivé ici pour savoir comment arrêter un système, vous devrez exécuter un programme externe à cet effet. Voir system.)

sin Image non disponible

 
Sélectionnez
sin EXPR
sin

Désolé, même si cet opérateur évoque des choses malicieuses aux anglophones(211), il ne fait que renvoyer le sinus de EXPR (exprimée en radians).

Pour l'opération inverse, vous pouvez utiliser la fonction asin des modules Math::Trig ou POSIX, ou utiliser cette relation :

 
Sélectionnez
sub asin { atan2($_[0], sqrt(1 -$_[0] * $_[0])) }

sleep

 
Sélectionnez
sleep EXPR
sleep

Cette fonction endort le script pendant EXPR secondes, ou éternellement si EXPR est omise. Elle renvoie le nombre de secondes réellement passées à dormir. Elle peut être interrompue en envoyant un signal SIGALRM au processus. Sur certains systèmes anciens, le repos peut durer jusqu'à une seconde de moins que ce que demandiez, selon la manière de compter les secondes. La plupart des systèmes modernes dorment toujours durant la période entière. Ils peuvent cependant sembler dormir plus que cela, car l'ordonnanceur d'un système multitâche peut ne pas donner tout de suite la main à votre processus. S'il est disponible, l'appel select (descripteurs de fichiers prêts) peut vous donner une meilleure résolution. Vous pouvez également employer syscall pour appeler les routines getitimer(2) et setitimer(2) supportée par certains systèmes Unix. Vous ne pouvez probablement pas mélanger des appels à alarm avec ceux à sleep, car sleep est souvent implémenté en utilisant alarm.

Voir également la fonction sigpause du module POSIX.

socket Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
socket SOCKET, DOMAINE, TYPE, PROTOCOLE

Cette fonction ouvre une socket du type spécifié et l'attache au handle de fichier SOCKET. DOMAIN, TYPE et PROTOCOLE sont spécifiés comme pour socket(2). Si le handle de fichier SOCKET est indéfini, il sera autovivifié. Avant d'utiliser cette fonction, votre programme doit contenir la ligne :

 
Sélectionnez
use Socket;

Cela vous donne accès aux constantes appropriées. La fonction renvoie vrai en cas de réussite. Voir les exemples dans la section « Sockets » au chapitre 16.

Sur les systèmes qui supportent le flag close-on-exec pour les fichiers, ce flag sera positionné pour le nouveau descripteur de fichier ouvert, comme le détermine la valeur de $^F. Voir la variable $^F ($SYSTEM_FD_MAX) au chapitre 28.

socketpair Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
socketpair SOCKET1, SOCKET2, DOMAINE, TYPE, PROTOCOLE

Cette fonction crée une paire de sockets non nommées dans le domaine spécifié, d'un type spécifié. DOMAINE, TYPE et PROTOCOLE sont spécifiés de la même manière que pour socketpair(2). Si l'un des arguments sockets (SOCKET1 ou SOCKET2) est indéfini, il sera autovivifié. La fonction renvoie vrai en cas de succès, sinon faux. Sur un système où socketpair(2) n'est pas implémenté, l'appel à cette fonction lève une exception.

Cette fonction est généralement utilisée juste avant un fork. L'un des processus résultants doit fermer SOCKET1 et l'autre SOCKET2. Vous pouvez utiliser ces sockets de manière bidirectionnelle, au contraire des handles de fichiers créés par la fonction pipe. Certains systèmes définissent pipe en termes de socketpair, auquel cas un appel à pipe(Lec, Ecr) est équivalent pour l'essentiel à :

 
Sélectionnez
use Socket;
socketpair(Lec, Ecr, AF_UNIX, SOCK_STREAM, PF_UNSPEC);
shutdown(Lec, 1);   # plus d'écritures pour le lecteur
shutdown(Ecr, 0);   # plus de lectures pour l'écrivain

Sur les systèmes qui supportent le flag close-on-exec pour les fichiers, ce flag sera positionné pour le nouveau descripteur de fichier ouvert, comme le détermine la valeur de $^F. Voir la variable $^F ($SYSTEM_FD_MAX) au chapitre 28. Voir également l'exemple à la fin de la section Communication bidirectionnelle au chapitre 16.

sort Image non disponible

 
Sélectionnez
sort SUB_UTILISATEUR LISTE
sort BLOC LISTE
sort LISTE

Cette fonction trie la LISTE et renvoie la valeur liste triée. Elle trie par défaut dans le sens de comparaison standard des chaînes (les valeurs indéfinies étant triées avant les chaînes vides définies, qui sont triées avant tout le reste). Lorsque le pragma use locale est actif, sort LISTE trie LISTE selon la locale courante LC_COLLATE.

SUB_UTILISATEUR, s'il est spécifié, est le nom d'un sous-programme qui renvoie un entier inférieur, égal ou supérieur à 0, selon la manière dont les éléments du tableau doivent être ordonnés. (Les opérateurs <=> et cmp peuvent être utilisés pour effectuer facilement des comparaisons de nombres et de chaînes pouvant donner trois résultats.) Si un SUB_UTILISATEUR est donné, mais que cette fonction est indéfinie, sort génère une exception.

Pour des raisons d'efficacité, le code d'appel normal des sous-programmes est court-circuité, ce qui a pour conséquences que : le sous-programme ne peut pas être récursif (ni contenir d'opérateur de contrôle de boucle qui vous ferait sortir du bloc ou de la routine) et que les deux éléments à comparer lui sont passés non via @_, mais en positionnant temporairement les variables globales par $a et $b dans le paquetage où sort a été compilé (voir les exemples ci-dessous). Les variables $a et $b étant passées en tant qu'alias des valeurs réelles, ne les modifiez pas dans le sous-programme.

Le sous-programme de comparaison doit bien se comporter. S'il renvoie des résultats inconsistants (en disant un jour que $x[1] est inférieur à $x[2] et en prétendant le contraire le lendemain), les conséquences sont aléatoires. (C'est une autre raison de ne pas modifier $a et $b.)

SUB_UTILISATEUR peut être un nom de variable scalaire (non indicée), dont la valeur fournit le nom du sous-programme à utiliser. (Un nom symbolique plutôt qu'une référence en dur est autorisé même lorsque le pragma use strict 'refs' est actif.) En lieu et place de SUB_UTILISATEUR, on peut fournir un BLOC, sorte de sous-programme anonyme en ligne.

Pour un tri numérique ordinaire, écrivez ceci :

 
Sélectionnez
sub numerique { $a <=> $b }
@tri_par_nombre = sort numerique 53,29,11,32,7;

Pour trier dans l'ordre décroissant, il vous suffit d'appliquer reverse après le sort, ou d'inverser l'ordre de $a et $b dans le sous-programme de tri :

 
Sélectionnez
@decroissant = reverse sort numerique 53,29,11,32,7;

sub inverse_numerique { $b <=> $a }
@decroissant = sort inverse_numerique 53,29,11,32,7;

Pour trier des chaînes sans tenir compte de la casse (majuscules/minuscules), passez $a et $b à lc avant la comparaison :

 
Sélectionnez
@desordonnee = qw/moineau Autruche ALOUETTE moqueurchat geaiBLEU/;
@ordonnee = sort { lc($a) cmp lc($b) } @desordonnee;

(Avec Unicode, l'emploi de lc pour la canonisation de la casse est plus ou moins préférable à l'utilisation de, uc car certaines langues différencient les majuscules pour les titres des majuscules ordinaires. Mais cela ne compte pas pour un tri ASCII basique, et si vous voulez trier convenablement de l'Unicode, vos routines de canonisation seront bien plus imaginatives que lc.)

Le tri des valeurs d'un hachage est une utilisation courante de la fonction sort. Par exemple, si un hachage %montant_ventes enregistre les ventes de différents services, une recherche dans le hachage à l'intérieur de la routine de tri permet aux clefs du hachage d'être triées selon leurs valeurs correspondantes :

 
Sélectionnez
# tri dans l'ordre décroissant des ventes par service
sub par_vente { $montant_ventes{$b} <=> $montant_ventes{$a} }

for $serv (sort par_vente keys %montant_ventes) {
    print "$serv => $montant_ventes{$serv}\n";
}

Vous pouvez effectuer des niveaux supplémentaires de tri en faisant des comparaisons en cascade à l'aide des opérateurs || ou or. Cela marche parfaitement, car les opérateurs de comparaison renvoient convenablement 0 pour une équivalence, ce qui les fait entrer dans la comparaison suivante. Ici les clefs de hachage sont triées tout d'abord selon les montants des ventes associées puis selon les clefs elles-mêmes (dans le cas où deux départements ou plus auraient le même montant de ventes) :

 
Sélectionnez
sub par_vente_puis_serv {
    $montant_ventes{$b} <=> $montant_ventes{$a}
        ||
    $a cmp $b
}

for $serv (sort par_vente_puis_serv keys %montant_ventes) {
    print "$serv => $montant_ventes{$serv}\n";
}

En supposant que @enregs est un tableau de références sur des hachages, dans lequel chaque hachage comporte des champs comme PRENOM, NOM, AGE, TAILLE et SALAIRE, la routine suivante met au début de la liste triée les enregistrements pour les personnes les plus riches, puis les plus grandes, ensuite les plus jeunes et enfin les premières dans l'ordre alphabétique :

 
Sélectionnez
sub prospecte {
    $b->{SALAIRE} <=> $a->{SALAIRE}
        ||
    $b->{TAILLE} <=> $a->{TAILLE}
        ||
    $a->{AGE} <=> $b->{AGE}
        ||
    $a->{NOM} cmp $b->{NOM}
        ||
    $a->{PRENOM} cmp $b->{PRENOM}
}
@triee = sort prospecte @enregs;

Toute information utile qui dérive de $a et de $b peut servir de base à une comparaison dans une routine de tri. Par exemple, si les lignes d'un texte doivent être triées selon des champs particuliers, split peut être utilisé dans la routine de tri pour dériver les champs :

 
Sélectionnez
@lignes_triees = sort {
    @champs_a = split /:/, $a;      # champs séparés par deux points
    @champs_b = split /:/, $b;

    $champs_a[3] <=> $champs_b[3]   # tri numérique sur le 4e champ, puis
        ||
    $champs_a[0] cmp $champs_b[0]   # tri de chaînes sur le 1er champ, puis
        ||
    $champs_b[2] <=> $champs_a[2]   # tri numérique décroissant sur le 3e
        ||                          # champ
    ...                             # etc.
} @lignes;

Toutefois, puisque sort exécute la routine de tri plusieurs fois en utilisant différentes paires de valeurs pour $a et $b, l'exemple précédent redécoupera chaque ligne avec split plus souvent que nécessaire.

Pour éviter le coût de dérivations répétées comme l'éclatement de lignes pour comparer leurs champs, exécutez la dérivation une seule fois par valeur avant le tri et sauvegardez l'information dérivée. Ici, on crée des tableaux anonymes pour encapsuler chaque ligne ainsi que le résultat de son éclatement :

 
Sélectionnez
@temp = map { [$_, split /:/] } @lignes;

Puis, on trie les références du tableau :

 
Sélectionnez
@temp = sort {
    @champs_a = @$a[1..$#$a];
    @champs_b = @$b[1..$#$b];

    $champs_a[3] <=> $champs_b[3]   # tri numérique sur le 4e champ, puis
        ||
    $champs_a[0] cmp $champs_b[0]   # tri de chaînes sur le 1er champ, puis
        ||
    $champs_b[2] <=> $champs_a[2]   # tri numérique décroissant sur le 3e
        ||                          # champ
    ...                             # etc.
} @temp;

Maintenant que les références du tableau sont triées, on peut récupérer les lignes d'origine à partir des tableaux anonymes :

 
Sélectionnez
@lignes_triees = map { $_->[0] } @temp;

Si l'on rassemble tout cela, cette technique map-sort-map, souvent appelée transformation schwartzienne(212), peut être accomplie en une seule instruction :

 
Sélectionnez
@lignes_triees = map { $_->[0] }
                 sort {
                     @champs_a = @$a[1..$#$a];
                     @champs_b = @$b[1..$#$b];
                     $champs_a[3] <=> $champs_b[3]
                        ||
                     $champs_a[0] cmp $champs_b[0]
                        ||
                     $champs_b[2] <=> $champs_a[2]
                        ||
                     ...
                 }
                 map { [$_, split /:/] } @lignes;

Ne déclarez pas $a et $b en tant que variables lexicales (avec my). Elles sont globales au paquetage (bien qu'exemptes des restrictions habituelles concernant les variables globales lorsque vous employez use strict). Vous devez cependant vous assurer que la routine de tri se trouve bien dans le même package, ou sinon qualifier $a et $b avec le nom du paquetage de l'appelant (voir la fonction caller).

Ceci étant dit, dans la version 5.6, vous pouvez écrire des sous-programmes de tri avec la méthode standard de passage d'arguments (et , sans coïncidence aucune, utiliser des sous-programmes XS comme routines de tri), pourvu que vous déclariez le sous-programme de tri avec un prototype valant ($$). Et dans ce cas, vous pouvez en fait déclarer $a et $b comme variables lexicales :

 
Sélectionnez
sub numerique ($$) {
    my ($a, $b) = @_;
    $a <=> $b;
}

Et un jour ou l'autre, lorsque des prototypes complets auront été implémentés, vous écrirez seulement :

 
Sélectionnez
sub numerique ($a, $b) { $a <=> $b }

et nous serons alors plus ou moins revenus à notre point de départ.

splice Image non disponible

 
Sélectionnez
splice TABLEAU, DECALAGE, LONGUEUR, LISTE
splice TABLEAU, DECALAGE, LONGUEUR
splice TABLEAU, DECALAGE
splice TABLEAU

Cette fonction enlève les éléments désignés par DECALAGE et LONGUEUR dans un TABLEAU, et les remplace par les éléments de LISTE, s'il en existe. Si DECALAGE est négatif, la fonction compte à rebours depuis la fin du tableau, mais si cela vous faisait atterrir avant le début du tableau, une exception est levée. Dans un contexte de liste, splice renvoie les éléments supprimés du tableau. Dans un contexte scalaire, elle renvoie le dernier élément enlevé ou undef s'il n'y en a pas. Si le nombre de nouveaux éléments n'est pas égal au nombre d'anciens éléments, le tableau augmente ou diminue en taille selon les besoins, et la position des éléments qui suivent cette tranche ajoutée ou enlevée est décalée en conséquence. Si LONGUEUR est omise, la fonction enlève tout à partir de DECALAGE. Si DECALAGE est omis, le tableau est vidé au fur et à mesure qu'il est lu. Les colonnes suivantes sont équivalentes (à supposer que $[ vaille 0) :

Méthode directe

Équivalent splice

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)

(@a, @a =())

splice(@a)

La fonction splice peut également servir à découper la liste d'arguments passée à un sous-programme. En supposant par exemple que les longueurs de liste sont passées avant les listes elles-mêmes :

 
Sélectionnez
sub eq_liste {      # compare deux valeurs de liste
    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);
    }
    return 1;
}
if (eq_liste($long, @machin[1..$long], scalar(@truc), @truc)) { }

Toutefois, il serait probablement plus propre de se contenter d'utiliser des références sur des tableaux pour faire cela.

split Image non disponible Image non disponible

 
Sélectionnez
split /MOTIF/, EXPR, LIMITE split /MOTIF/, EXPR
split /MOTIF/
split

Cette fonction recherche des délimiteurs dans une chaîne EXPR et l'éclate en une liste de sous-chaînes, en renvoyant la valeur liste résultante dans un contexte de liste, ou le nombre de sous-chaînes dans un contexte scalaire.(213) Les délimiteurs sont déterminés par la correspondance répétée d'un motif, en utilisant l'expression régulière donnée dans MOTIF. Les délimiteurs peuvent donc être de n'importe quelle taille et ne sont pas forcément la même chaîne à chaque recherche. (Les délimiteurs ne sont généralement pas renvoyés, mais voyez les exceptions ci-dessous.) Si le MOTIF ne correspond à rien, split renvoie la chaîne d'origine comme une sous-chaîne unique. S'il trouve une occurrence, vous obtenez deux sous-chaînes, et ainsi de suite. Vous pouvez donner au MOTIF des modificateurs d'expressions régulières, comme /MOTIF/i, /MOTIF/x, etc. Lorsque vous éclatez avec un motif valant /^/, le modificateur //m est implicite.

Si LIMITE est spécifiée et positive, la fonction éclate la chaîne en, au plus, ce nombre de champs (bien qu'elle puisse l'éclater en moins si elle ne trouve pas assez de délimiteurs). Si LIMITE est négative, elle est traitée comme si une LIMITE arbitrairement grande avait été spécifiée. Si LIMITE est omise, les champs nuls qui restent sont éliminés du résultat (ce dont les utilisateurs potentiels de pop feraient bien de se souvenir). Si EXPR est omise, la fonction éclate la chaîne $_. Si MOTIF est également omis ou s'il s'agit d'un espace littéral, " ", la fonction éclate sur les caractères d'espacement, /s+/, après avoir éliminé tout espacement en début de chaîne.

On peut éclater des chaînes de n'importe quelle longueur :

 
Sélectionnez
@cars   = split //,  $mot;
@champs = split /:/, $ligne;
@mots   = split " ", $paragraphe;
@lignes = split /^/, $tampon;

Un motif capable de correspondre soit à la chaîne vide, soit à quelque chose de plus long que la chaîne vide (par exemple, un motif composé d'un seul caractère modifié par un * ou un ?) éclatera la valeur de EXPR en caractères séparés partout où il correspond à la chaîne vide entre les caractères ; les correspondances non nulles passeront outre les occurrences du délimiteur comme habituellement. (En d'autres termes, un motif ne trouvera pas de correspondance en plus d'un endroit, même avec une longueur de zéro.) Par exemple :

 
Sélectionnez
print join ':', split / */, 'à la vôtre';

produira « à:l:a:v:o:t:r:e ». Les espaces ont disparu, car ils ont provoqué une correspondance non nulle. Dans un cas trivial, le motif nul // se contente d'éclater la chaîne en caractères séparés, et les espaces ne disparaissent pas. (Pour une correspondance de motif normale, un motif // répéterait le dernier motif de correspondance réussie, mais le motif de split ne tombe pas dans cette crevasse.)

Le paramètre LIMITE peut être utilisé pour n'éclater qu'une partie d'une chaîne :

 
Sélectionnez
($login, $mot_de_passe, $reste) = split /:/, $_, 3;

Nous vous encourageons à éclater des listes de noms comme ceci afin d'autodocumenter votre code. (Pour des raisons de vérification d'erreurs, remarquez que $reste serait indéfini s'il y avait moins de 3 champs.) Quand une liste se voit assigner une valeur, si LIMITE est omise, Perl fournit une LIMITE supérieure de 1 au nombre de variables de la liste pour éviter un travail inutile. Pour la liste ci-dessus, LIMITE aurait été de 4 par défaut, et $reste n'aurait reçu que le troisième champ et non le reste de la ligne. Dans des applications où le temps compte, il vaut mieux ne pas éclater en plus de champs que ce dont vous avez vraiment besoin. (Le problème avec les langages puissants, c'est qu'ils vous laissent parfois être des idiots en puissance.)

Nous avons dit plus haut que les délimiteurs n'étaient pas renvoyés, mais si le MOTIF contient des parenthèses, les champs habituellement renvoyés viennent s'intercaler entre chaque occurrence des délimiteurs entre parenthèses qui est également incluse dans la liste résultante. Voici un exemple simple :

 
Sélectionnez
split /([-,])/, "1-10,20";

produit la valeur de liste :

 
Sélectionnez
(1, '-', 10, ',', 20)

S'il y a plus de parenthèses, un champ est renvoyé pour chaque paire, même si certaines ne donnent pas de correspondances, auquel cas des valeurs indéfinies sont renvoyées à ces positions. Ainsi, si vous écrivez :

 
Sélectionnez
split /(-)|(,)/, "1-10,20";

vous obtiendrez la valeur :

 
Sélectionnez
(1, '-', undef, 10, undef, ',', 20)

L'argument /MOTIF/ peut être remplacé par une expression spécifiant les motifs qui varient à l'exécution. Comme pour les motifs ordinaires, pour ne compiler à l'exécution qu'une seule fois, utilisez /$variable/o.

Il existe un cas spécial où la spécification d'un espace unique ("") éclate sur les caractères d'espacement tout comme split sans argument. split(" ") peut donc être utilisé pour émuler le comportement de awk par défaut. Alors qu'au contraire split(/ /) vous donnera autant de champs nuls initiaux qu'il existe d'espaces en en-tête. (Par ailleurs, si l'on fournit une chaîne au lieu d'une expression rationnelle, elle sera de toute façon interprétée comme une expression rationnelle.) Vous pouvez utiliser cette propriété pour supprimer les espaces au début et à la fin d'une chaîne et pour rassembler les séquences de caractères d'espacement consécutifs en un seul espace :

 
Sélectionnez
$chaine = join(' ', split(' ', $chaine));

L'exemple suivant éclate un en-tête de message RFC-822 en un hachage contenant $tete{$Date}, $tete{Subject}, et ainsi de suite. Il utilise l'astuce d'assigner une liste de paire à un hachage, en se basant sur le fait que les délimiteurs alternent avec des champs délimités. Il emploie les parenthèses pour renvoyer les parties de chaque délimiteur comme faisant partie de la valeur de liste renvoyée. Comme le motif de split garantit le renvoi des éléments en paires par la vertu de contenir un seul jeu de parenthèses, l'affectation du hachage est sure de recevoir une liste composée de paires clef/valeur, où chaque clef est le nom d'un champ d'en-tête. (Cette technique fait malheureusement perdre des informations sur plusieurs lignes avec le même champ de clef, comme les lignes Received-By. Ah, et puis zut…)

 
Sélectionnez
$entete =~ s/\n\s+/ /g; # Réunit les lignes de continuation.
%tete = ('PREAMBULE', split /^(\S*?):\s*/m, $entete);

L'exemple suivant traite les entrées d'un fichier Unix passwd(5). Vous pourriez éviter le chomp, auquel cas $shell se terminerait par un saut de ligne.

 
Sélectionnez
open MOT_DE_PASSE, '/etc/passwd';
while (<MOT_DE_PASSE>) {
    chomp;      # supprime le saut de ligne final
    ($login, $mot_de_passe, $uid, $gid, $nom_reel, $rep, $shell) =
        split /:/;
    ...
}

Voici comment traiter chaque mot de chaque ligne de chaque fichier d'entrée pour créer un hachage des fréquences de mots :

 
Sélectionnez
while (<>) {
    foreach $mot (split) {
        $compteur{$mot}++;
    }
}

L'inverse de split est effectué par join (sauf que join ne peut joindre qu'avec le même délimiteur entre tous les champs). Pour éclater une chaîne sur des champs de longueur fixe, employez unpack.

sprintf

 
Sélectionnez
sprintf FORMAT, LISTE

Cette fonction renvoie une chaîne formatée suivant les conventions habituelles de printf gouvernées par la fonction sprintf de la bibliothèque C. Voir sprintf (3) ou printf (3) sur votre système pour une explication des principes généraux. La chaîne FORMAT contient du texte comprenant des spécificateurs de champs auxquels les éléments de LISTE sont substitués, à raison d'un élément par champ.

Perl réalise son propre formatage pour sprintf — il émule la fonction C sprintf, mais il ne l'utilise pas.(214) Il en résulte que toutes les extensions non standards dans votre fonction sprintf (3) locale ne sont pas accessibles depuis Perl.

Le sprintf de Perl permet d'utiliser les conversions universellement connues qui sont montrées dans le tableau 29-4.

Tableau 29-4. Formats pour sprintf

Champ

Signification

%%

Un signe pourcent.

%c

Un caractère avec le nombre donné.

%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 à virgule flottante, en notation scientifique.

%f

Un nombre à virgule flottante, en notation décimale fixe.

%g

Un nombre à virgule flottante, en notation %e ou %f.

De plus, Perl permet d'utiliser les conversions suivantes, largement supportées :

Champ

Signification

%X

Comme %x, mais avec des lettres majuscules.

%E

Comme %e, mais avec un « E » majuscule.

%G

Comme %g, mais avec un « E » majuscule (si c'est applicable).

%b

Un entier non signé, en binaire.

%p

Un pointeur (affiche l'adresse de la valeur Perl en hexadécimal).

%n

Spécial : sauvegarde le nombre de caractères de sortie jusque là dans la prochaine variable de la liste d'arguments.

Enfin, pour une compatibilité antérieure (et nous voulons vraiment dire « antérieure »), Perl permet d'utiliser ces conversions inutiles, mais largement supportées :

Champ

Signification

%i

Un synonyme pour %d.

%D

Un synonyme pour %ld.

%U

Un synonyme pour %lu.

%O

Un synonyme pour %lo.

%F

Un synonyme pour %f.

Perl permet d'utiliser les flags suivants universellement connus entre le % et le caractère de conversion :

Flag

Signification

espace

Préfixe un nombre positif par un espace.

+

Préfixe un nombre positif par un signe plus.

-

Justifie le champ vers la gauche.

0

Utilise des zéros, et non des espaces, pour justifier vers la droite.

#

Préfixe un octal non nul par "0" et un hexadécimal non nul par "0x".

nombre

Largeur minimale du champ.

.nombre

« Précision » : chiffres après la virgule pour les nombres à virgule flottante, longueur maximale pour les chaînes, longueur minimale pour les entiers.

l

Interprète l'entier comme un type C long ou unsigned long.

h

Interprète l'entier comme un type C short ou unsigned short (si aucun flag n'est fourni, l'entier est interprété comme un type C int ou unsigned).

Il existe également ces deux flags spécifiques à Perl :

Flag

Signification

V

Interprète l'entier comme le type entier standard de Perl.

v

Interprète la chaîne comme un vecteur d'entiers, affichés comme des nombres séparés soit par des points, soit par une chaîne arbitraire reçue depuis la liste d'arguments lorsque le flag est précédé par *.

Si votre Perl connaît les « quads » (entiers de 64 bits) soit parce que la plate-forme les supporte nativement, soir parce que Perl a été spécialement compilé avec cette possibilité, alors les caractères duoxXb iDUO affichent des quads et ils peuvent optionnellement être précédés par ll, L ou q. Par exemple, %lld %16LX %qo. Si Perl connaît les « longs doubles » (ceci requiert que la plate-forme supporte les longs doubles), les flags efgEFG peuvent optionnellement être précédé par ll ou L. Par exemple, %llf %Lf.

Là où un nombre pourrait apparaître dans les flags, un astérisque (« * ») peut être utilisé en lieu et place, auquel cas Perl utilise la prochaine entité dans la liste d'arguments comme le nombre donné (c'est-à-dire, comme le champ de largeur ou de précision). Si un champ de largeur, obtenu avec « * » est négatif, il entraîne les mêmes effets qu'un flag « - » : une justification vers la gauche.

Le flag v est utilisé pour afficher les valeurs ordinales de caractères dans des chaînes arbitraires :

 
Sélectionnez
sprintf "la version est v%vd\n", $^V;         # version de Perl
sprintf "l'adresse est %vd\n", $adr;          # adresse IPv4
sprintf "l'adresse est %*vX\n", $adr;         # adresse IPv6
sprintf "les bits sont %*vb\n", " ", $bits;   # chaînes de bits aléatoires

sqrt Image non disponible Image non disponible

 
Sélectionnez
sqrt EXPR
sqrt

Cette fonction renvoie la racine carrée de EXPR. Pour les autres racines, comme la racine cubique, vous pouvez utiliser l'opérateur ** pour élever quelque chose à une puissance fractionnaire. N'essayez par l'une de ces approches avec des nombres négatifs, car cela devient un problème légèrement plus complexe (et lève une exception). Mais il existe un module standard pour s'occuper de cela aussi :

 
Sélectionnez
use Math::Complex;
print sqrt(-2);      # affiche 1.4142135623731i

srand

 
Sélectionnez
srand EXPR
srand

Cette fonction positionne la « graine » aléatoire pour l'opérateur rand. Si EXPR est omise, elle utilise une valeur semi-aléatoire fournie par le noyau (si il supporte le périphérique /dev/urandom) ou basée sur l'heure et la date courante et le PID, entre autres choses. Il n'est généralement pas du tout nécessaire d'appeler srand, car si on ne l'appelle pas explicitement, l'opérateur rand l'invoque implicitement. Toutefois, ce n'était pas vrai dans les versions de Perl antérieures à 5.004, donc si votre script a besoin de tourner avec des versions de Perl plus anciennes, il doit appeler srand.

Les programmes appelés fréquemment (comme les scripts CGI) qui n'utilisent que time ^ $$ pour générer une graine aléatoire peuvent les deux tiers du temps être victimes de la propriété mathématique a^b == (a+1)^(b+1). Alors, ne faites pas cela. À la place, utilisez :

 
Sélectionnez
srand( time() ^ ($$ + ($$ << 15)) );

Vous aurez besoin de plus d'une graine plus aléatoire que celle par défaut pour faire de la cryptographie. Sur certains systèmes le périphérique /dev/urandom est approprié. Sinon, la méthode habituelle est de faire une somme de contrôle (N.d.T. : checksum) sur la sortie compressée d'un ou plusieurs programmes donnant l'état du système d'exploitation en tenant compte du changement rapide de ces états. Par exemple :

 
Sélectionnez
srand (time ^ $$ ^ unpack "%L*", 'ps wwaxl | gzip');

Si vous êtes particulièrement concernés par ce problème, regardez le module Math::TrulyRandom dans CPAN.

N'appelez pas srand plusieurs fois dans un programme à moins de savoir exactement ce que vous faites et pourquoi vous le faites. Le but de cette fonction est d'initialiser une « graine » pour la fonction rand pour qu'elle puisse produire un résultat différent à chaque lancement du programme. Ne l'appelez qu'une seule fois au début, faute de quoi rand ne générera pas de nombres aléatoires !

stat Image non disponible Image non disponible Image non disponible

 
Sélectionnez
stat HANDLE_FICHIER
stat EXPR
stat

Dans un contexte scalaire, cette fonction renvoie un booléen indiquant si l'appel a réussi. Dans un contexte de liste, elle renvoie une liste de 13 éléments donnant l'état d'un fichier, qu'il soit ouvert via HANDLE_FICHIER ou nommé par EXPR. Elle est généralement utilisée comme suit :

 
Sélectionnez
($periph,$inode,$mode,$nb_liens,$uid,$gid,$type_periph,$taille,
    $date_a,$date_m,$date_c, $taille_bloc,$blocs)
        = stat $nom_fichier;

Tous les champs ne sont pas supportés par tous les systèmes d'exploitation, les champs non supportés renvoient 0. Voici les significations des champs :

Index

Champ

Signification

0

$periph

Numéro de périphérique du système de fichier.

1

$inode

Numéro d'inode.

2

$mode

Mode du fichier (type et permissions).

3

$nb_liens

Nombre de liens (en dur) vers le fichier.

4

$uid

UID numérique du propriétaire du fichier.

5

$gid

GID numérique du groupe désigné du fichier.

6

$type_periph

Identificateur du périphérique (pour les fichiers spéciaux seulement).

7

$taille

Taille totale du fichier, en octets.

8

$date_a

Dernière date d'accès au fichier en secondes depuis l'origine.

9

$date_m

Dernière date de modification du fichier en secondes depuis l'origine.

10

$date_c

Date de changement de l'inode (et non de création !) en secondes depuis l'origine.

11

$taille_bloc

Taille de bloc préféré pour les entrées/sorties sur le système de fichier.

12

$blocs

Nombre de blocs réellement alloués.

$periph et $inode, pris ensemble, identifient un fichier de manière unique. Les $taille_bloc et $blocs ne sont définis que sur les systèmes de fichiers dérivés de BSD. Le champ $blocs (s'il est défini) est donné en blocs de 512 octets. La valeur de $blocs*512 peut énormément différer de $taille pour des fichiers contenant des blocs non alloués, ou « trous », qui ne sont pas comptés dans $blocs. Si on passe à stat le handle de fichier spécial composé d'un souligné, aucune collection d'informations n'a lieu, mais le contenu actuel de la structure datant du dernier stat, lstat ou du dernier test de fichier en dépendant (comme -r, -w ou -x) sont renvoyés.

Comme le mode comprend à la fois le type du fichier et ses permissions, vous devez masquer la partie du type et faire printf ou sprintf avec "%o" si vous voulez voir les permissions réelles :

 
Sélectionnez
$mode = (stat($nom_fichier))[2];
printf "Les permissions sont %04o\n", $mode & 07777;

Le module File::stat fournit un mécanisme d'accès simplifié, orienté « par nom » :

 
Sélectionnez
use File::stat; $sb = stat($nom_fichier);
printf "Le fichier est %s, sa taille %s, ses permissions %04o, date_m %s\n",
    $nom_fichier, $sb->size, $sb->mode & 07777,
    scalar localtime $sb->mtime;

Vous pouvez également importer les définitions symboliques des divers bits de mode depuis le module Fcntl. Voir la documentation en ligne pour plus de détail.

Astuce : si vous n'avez seulement besoin que de la taille du fichier, essayez l'opérateur de test de fichier -s, qui renvoie directement la taille en octets. Il existe également des tests de fichiers qui renvoient l'âge du fichier en nombre de jours.

study Image non disponible

 
Sélectionnez
study SCALAIRE
study

Cette fonction prend du temps supplémentaire pour étudier SCALAIRE afin d'anticiper de nombreuses recherches de motifs sur la chaîne avant qu'elle ne soit ensuite modifiée. Ceci peut ou non faire gagner du temps, selon la nature et le nombre de motifs de vos recherches, et selon la distribution des fréquences de caractères dans la chaîne recherchée — il vaut mieux que vous compariez les temps d'exécution avec et sans study pour voir ce qui tourne le plus vite. Les boucles qui cherchent de nombreuses chaînes courtes et constantes (y compris les parties constantes de motifs plus complexes) sont celles qui bénéficieront le plus de study. Si tous vos motifs sont des chaînes constantes, ancrées au début, study ne vous sera d'aucun secours, car aucune scrutation ne sera effectuée. Vous ne pouvez avoir qu'un seul study (N.d.T. : étude) actif à la fois ; si vous étudiez un scalaire différent, le premier est « dé-étudié ».

study fonctionne de la manière suivante : une liste chaînée de chacun des caractères de la chaîne est construite de façon à savoir, par exemple, où se trouvent tous les caractères « k ». Pour chaque chaîne, le caractère le plus rare est sélectionné, en se fondant sur des tables de fréquence statiques construites par des programmes C sur du texte anglais. Seuls les endroits contenant ce caractère rare sont examinés.

Par exemple, voici une boucle qui insère des entrées d'index avant toute ligne contenant un certain motif :

 
Sélectionnez
while (<>) {
    study;
    print ".IX machin\n"  if /\bmachin\b/;
    print ".IX truc\n"    if /\btruc\b/;
    print ".IX bidule\n"  if /\bbidule\b/;
    ...
    print;
}

Pendant cette recherche sur /\bmachin\b/, seuls les endroits de $_ contenant « h » seront examinés, car « h » est plus rare que les autres lettres. En général, le gain est indiscutable, sauf dans des cas pathologiques. La seule question est de savoir si cela fait gagner plus de temps que de construire d'abord la liste chaînée.

Si vous devez rechercher des chaînes que vous ne connaissez qu'au moment de l'exécution, vous pouvez construire une boucle complète sous forme de chaîne et l'eval uer pour éviter la recompilation systématique de tous vos motifs. Ceci, associé à $/ pour entrer des fichiers complets en un seul enregistrement, peut être extrêmement rapide, souvent plus rapide que des programmes spécialisés comme fgrep(1). La routine suivante scrute une liste de fichiers (@fichiers) pour trouver une liste de mots @mots), et affiche les noms des fichiers contenant une correspondance sans tenir compte de la casse :

 
Sélectionnez
$recherche = 'while (<>) { study;';
foreach $mot (@mots) {
    $recherche .= "++\$vu{\$ARGV} if /\\b$mot\\b/i;\n";
}
$recherche .= "}";
@ARGV = @fichiers;
undef $/;               # gobe chaque fichier en entier
eval $recherche;        # pied au plancher
die $@ if $@            # en cas d'échec de eval
$/ = "\n";              # remet le délimiteur d'entrée normal
foreach $fichier (sort keys(%vu)) {
    print $fichier, "\n";
}

Maintenant que nous avons l'opérateur qr//, les eval s compliqués à l'exécution comme celui ci-dessus sont moins indispensables. Ceci fait la même chose :

 
Sélectionnez
@motifs = ();
foreach $mot (@mots) {
    push @motifs, qr/\b$mot\b/i;
}
@ARGV = @fichiers;
undef $/;       # gobe chaque fichier en entier
while (<>) {
    for $motif (@motifs) {
        $vu{$ARGV}++ if /$motif/;
    }
}
$/ = "\n";      # remet le délimiteur d'entrée normal
foreach $fichier (sort keys(%vu)) {
    print $fichier, "\n";
}

sub

Déclarations nommées :

 
Sélectionnez
sub NOM PROTO ATTRS
sub NOM ATTRS
sub NOM PROTO
sub NOM

Définitions nommées :

 
Sélectionnez
sub NOM PROTO ATTRS BLOC
sub NOM ATTRS BLOC
sub NOM PROTO BLOC
sub NOM BLOC

Définitions anonymes :

 
Sélectionnez
sub PROTO ATTRS BLOC
sub ATTRS BLOC
sub PROTO BLOC
sub BLOC

La syntaxe des déclarations et définitions de sous-programmes paraît compliquée, mais elle est vraiment assez simple en pratique. Tout est basé sur la syntaxe :

 
Sélectionnez
sub NOM PROTO ATTRS BLOC

Les quatre arguments sont tous optionnels ; la seule restriction est que les champs présents doivent être présents dans cet ordre ; et que vous devez utiliser au moins un des champs NOM ou BLOC. Pour le moment nous ignorerons les champs PROTO et ATTRS ; ce sont seulement des modificateurs de la syntaxe de base. Les champs NOM et BLOC sont les parties importantes pour faire court :

  • Si vous n'avez qu'un NOM mais pas de BLOC, il s'agit d'une déclaration de ce nom (et si jamais vous voulez appelez le sous-programme, vous devrez fournir plus tard une définition avec à la fois NOM et BLOC). Les déclarations nommées sont spécialement utiles pour que l'analyseur syntaxique traite un nom de manière spéciale s'il sait qu'il s'agit d'un sous-programme défini par l'utilisateur. Vous pouvez appeler ceci un sous-programme ou une fonction ou encore un opérateur, exactement comme les fonctions internes. Ces déclarations sont parfois appelées déclarations anticipées.
  • Si vous avez à la fois un NOM et un BLOC, il s'agit d'une définition standard d'un sous-programme nommé (et également une déclaration, si vous n'avez pas déclaré le nom précédemment). Les définitions nommées sont spécialement utiles, car le BLOC associe un véritable sens (le corps du sous-programme) à la déclaration. C'est exactement ce que cela signifie lorsque nous disons qu'elle définit le sous-programme au lieu de simplement le déclarer. La définition ressemble toutefois à la déclaration, en ce que le code l'encadrant ne la voit pas, et qu'elle ne renvoie pas de valeur en ligne avec laquelle vous pourriez référencer le sous-programme.
  • Si vous n'avez qu'un BLOC mais pas de NOM, il s'agit d'une définition sans nom, c'est-à-dire, un sous-programme anonyme. Puisqu'elle n'a pas de nom, ce n'est absolument pas une déclaration, mais un opérateur réel qui renvoie à l'exécution une référence vers le corps du sous-programme anonyme. C'est extrêmement utile pour traiter du code en tant que donnée. Cela vous permet de passer de menus morceaux de code en tant que fonctions de rappel (N.d.T. : callbacks), ou peut-être même en tant que fermetures si l'opérateur de définition sub se réfère à des variables lexicales qui se trouvent à l'extérieur de son propre code. Cela signifie que différents appels au même opérateur sub feront la comptabilité nécessaire pour conserver la visibilité de la « version » correcte de chacune de ces variables lexicales le temps où la fermeture existe, même si la portée d'origine des variables lexicales a été détruite.

Dans chacun de ces trois cas, soit l'un, soit les deux arguments PROTO et ATTRS peuvent apparaître après le NOM et avant le BLOC. Un prototype est une liste de caractères entre parenthèses qui indique à l'analyseur syntaxique comment traiter les arguments d'une fonction. Les attributs sont introduits par un deux-points et fournissent des informations supplémentaires à l'analyseur concernant la fonction. Voici une définition typique qui inclut tous les quatre champs :

 
Sélectionnez
num_ch_cmp ($$) : locked {
    my ($a, $b) = @_;
    return $a <=> $b || $a cmp $b;
}

pour plus de détails sur les listes d'attributs et leur manipulation, voir le pragma attributes au chapitre 31. Voir également le chapitre 6 et la section Sous-programmes anonymes au chapitre 8.

substr Image non disponible Image non disponible Image non disponible

 
Sélectionnez
subtsr EXPR, DECALAGE, LONGUEUR, REMPLACEMENT
subtsr EXPR, DECALAGE, LONGUEUR
subtsr EXPR, DECALAGE

Cette fonction extrait une sous-chaîne de la chaîne donnée par EXPR et la renvoie. La sous-chaîne est extraite en commençant à DECALAGE caractères depuis le premier. (Remarque : si vous avez fait le malin avec $[, le début de la chaîne n'est pas à 0, mais comme vous avez été sage (n'est-ce pas ?) il n'y a pas de problème). Si DECALAGE est négatif, la sous-chaîne démarre à cette distance de la fin de la chaîne. Si LONGUEUR est omise, toute la fin de la chaîne est renvoyée. Si LONGUEUR est négative, la longueur est calculée pour laisser ce nombre de caractères depuis la fin de la chaîne. Sinon, LONGUEUR indique la longueur de la sous-chaîne à extraire, ce à quoi vous pouviez vous attendre.

Vous pouvez utiliser substr comme une lvalue (quelque chose à laquelle on peut assigner une valeur), auquel cas EXPR doit aussi en être une. Si l'on assigne une valeur d'une longueur inférieure à LONGUEUR, la chaîne sera raccourcie et si l'on assigne une valeur d'une longueur supérieure à LONGUEUR, la chaîne s'allongera pour s'en accommoder. Il vous faudra peut-être compléter ou couper la valeur avec sprintf ou l'opérateur x pour conserver une chaîne de même longueur. Si vous tentez une affectation dans une zone non allouée après la fin la chaîne, substr lève une exception.

Pour préfixer la valeur courante de $var par la chaîne "Achille" , écrivez :

 
Sélectionnez
substr($var, 0, 0) = "Achille";

Pour remplacer le premier caractère de $var par "Talon" , écrivez :

 
Sélectionnez
substr($var, 0, 1) = "Talon";

Et enfin, pour remplacer le dernier caractère de $var par "Lefuneste" , écrivez :

 
Sélectionnez
substr($var, -1, 1) = "Lefuneste";

Une alternative à l'utilisation de substr en tant que lvalue est l'emploi de la chaîne REMPLACEMENT comme quatrième argument. Ceci vous permet de remplacer des parties de l'EXPR et de renvoyer ce qu'il y avait avant en une seule opération, exactement comme vous pouvez le faire avec splice. Le prochain exemple remplace également le dernier caractère de $var par "Lefuneste" et met la chaîne remplacée dans $avant :

 
Sélectionnez
$avant = substr($var, -1, 1, "Lefuneste");

substr en tant que lvalue n'est pas réservée seulement aux affectations. Cet exemple remplace les espaces par des points, mais seulement dans les 10 derniers caractères de la chaîne :

 
Sélectionnez
substr($var, -10) =~ s/ /./g;

symlink Image non disponible Image non disponible Image non disponible

 
Sélectionnez
symlink ANCIEN_NOM, NOUVEAU_NOM

Cette fonction crée un nouveau nom de fichier lié symboliquement à l'ancien nom de fichier. La fonction renvoie vrai en cas de succès, sinon faux. Sur les systèmes ne supportant pas les liens symboliques, elle lève une exception à l'exécution. Pour éviter cela, utilisez eval pour intercepter l'erreur potentielle :

 
Sélectionnez
$symlink_existe = eval { symlink("", ""); 1 };

Ou utilisez le module Config. Soyez prudent si vous fournissez un lien symbolique relatif, car cela sera interprété relativement à la position du lien symbolique lui-même, et non à votre répertoire de travail courant.

Voir également link et readlink plus haut dans ce chapitre.

syscall Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
syscall LISTE

Cette fonction invoque l'appel système (nous voulons dire un appel système, et pas une commande shell) spécifié dans le premier argument de la liste en passant les éléments restants comme arguments à l'appel système. (Beaucoup d'entre eux sont maintenant plus directement disponibles par le biais de modules comme POSIX). La fonction lève une exception si syscall(2) n'est pas implémenté.

Les arguments sont interprétés comme suit : si un argument donné est numérique, l'argument est passé comme un entier C. Sinon, c'est un pointeur sur la valeur chaîne qui est passé. Vous devez vous assurer que la chaîne est assez longue pour recevoir tout résultat pouvant y être écrit ; sinon vous chercher la copie du cœur du programme (core dump). Vous ne pouvez pas utiliser une chaîne littérale (ou toute autre chaîne en lecture seule) comme argument de syscall car Perl doit prévoir que l'on puisse écrire dans tout pointeur de chaîne. Si vos arguments entiers ne sont pas des littéraux et n'ont jamais été interprétés dans un contexte numérique, vous devrez peut-être leur ajouter 0 pour les forcer à ressembler à des nombres.

syscall renvoie toute valeur retournée par l'appel système invoqué. D'après les conventions de codage C, si l'appel système échoue, syscall renvoie -1 et positionne $! (errno). Certains appels système renvoient légitimement -1 en cas de réussite. La manière appropriée de gérer de tels appels système et d'assigner $!=0; avant l'appel et de vérifier la valeur de $! si syscall renvoie -1.

Tous les appels système ne sont pas accessibles de cette manière. Par exemple, Perl peut passer jusqu'à 14 arguments à votre appel système, ce qui doit normalement suffire en pratique. Il existe cependant un problème avec les appels système qui renvoient des valeurs multiples. Prenez syscall(&SYS_pipe) : il renvoie le numéro de fichier de l'extrémité de lecture du pipe qu'il crée. Il n'y a aucun de moyen de récupérer le numéro de fichier de l'autre extrémité. Vous pouvez éviter ce type de problème en utilisant pipe à la place. Pour résoudre le problème générique, écrivez des XSUB (modules de sous-programmes externes, un dialecte de C) pour accéder aux appels système directement. Puis mettez votre nouveau module sur CPAN et devenez mondialement populaire.

Le sous-programme suivant renvoie l'heure courante en tant que nombre à virgule flottante plutôt que le nombre entier de secondes renvoyé par time. (Il ne fonctionne que sur les machines qui supporte l'appel système gettimeofday(2).)

 
Sélectionnez
sub heure_precise() {
    package main;   # pour le prochain require
    require 'syscall.ph';
    # prépare le tampon pour qu'il soit de la taille de deux entiers
    # longs de 32-bits
    my $tv = pack("LL", ());
    syscall(&SYS_gettimeofday, $tv, undef) >=0
        or die "gettimeofday : $!";
    my ($secondes, $microsecondes) = unpack("LL", $tv);
    return $secondes + ($microsecondes /1_000_000);
}

Imaginez que Perl ne supporte pas l'appel système setgroups(2)(215), mais que votre noyau l'implémente. Vous pourriez toujours l'atteindre de cette manière :

 
Sélectionnez
require 'syscall.ph';
syscall(&SYS_setgroups; scalar @nouveaux_gids, pack("i*", @nouveaux_gids))
    or die "setgroups : $!";

Vous devrez peut-être lancer h2ph, comme l'indiquent les instructions d'installations de Perl, pour créer syscall.ph. Certains systèmes peuvent nécessiter à la place un canevas pour pack de "II". Encore plus perturbant, la fonction syscall suppose une équivalence de taille entre les types C int, long et char*. Essayez de ne pas considérer syscall comme le parangon de la portabilité.

Voir le module Time::HiRes de CPAN pour une approche plus rigoureuse des problèmes de dates et d'heures d'une granularité plus fine.

sysopen Image non disponible Image non disponible

 
Sélectionnez
sysopen HANDLE_FICHIER, NOM_FICHIER, MODE, MASQUE
sysopen HANDLE_FICHIER, NOM_FICHIER, MODE

La fonction sysopen ouvre le fichier dont le nom est donné par NOM_FICHIER et l'associe avec HANDLE_FICHIER. Si HANDLE_FICHIER est une expression, sa valeur est employée comme le nom du handle de fichier ou comme une référence sur ce dernier. Si HANDLE_FICHIER est une variable dont la valeur est indéfinie, une valeur sera créée pour vous. La valeur de retour est vrai si l'appel réussit, sinon faux.

Cette fonction est une interface directe à l'appel open(2) de votre système d'exploitation suivi par un appel de bibliothèque fdopen(3). En tant que tel, vous devrez ici prétendre être un peu un programmeur C. Les valeurs possibles et les flags de bits du paramètre MODE sont disponibles via le module Fcntl. Puisque des systèmes différents supportent des flags différents, ne comptez pas sur la disponibilité de tous les flags sur votre système. Consultez votre page de manuel open(2) ou son équivalent local pour plus de détails. Néanmoins, les flags suivants devraient être présents sur tout système disposant d'une bibliothèque C raisonnable :

Flag

Signification

O_RDONLY

Lecture seule.

O_WRONLY

Écriture seule.

O_RDWR

Lecture et écriture.

O_CREAT

Crée le fichier s'il n'existe pas.

O_EXCL

Échoue si le fichier existe déjà.

O_APPEND

Ajoute à la fin du fichier.

O_TRUNC

Tronque le fichier.

O_NONBLOCK

Accès non bloquant.

Beaucoup d'autres options sont toutefois possibles. Voici quelques flags moins communs :

Flag

Signification

O_NDELAY

Ancien synonyme pour O_NONBLOCK

O_SYNC

Écrit un bloc jusqu'à ce que la donnée soit physiquement écrite vers le matériel sous-jacent. On peut également voir ici O_ASYNC, O_DSYNC et O_RSYNC.

O_EXLOCK

flock avec LOCK_EX (à titre consultatif seulement).

O_SHLOCK

flock avec LOCK_SH (à titre consultatif seulement).

O_DIRECTOR

Échoue si le fichier n'est pas un répertoire.

O_NOFOLLOW

Échoue si le dernier composant du chemin est un lien symbolique.

O_BINARY

Effectue un binmode pour les systèmes Microsoft. Un O_TEXT peut également parfois exister pour obtenir le comportement opposé.

O_LARGEFILE

Certains systèmes en ont besoin pour les fichiers de plus de 2 GO.

O_NOCTTY

L'ouverture d'un fichier de terminal ne le fera pas devenir le terminal de contrôle du processus si vous n'en aviez pas encore. Habituellement ce flag n'est plus nécessaire.

Le flag O_EXCL ne sert pas pour les verrous : ici, l'exclusivité signifie que si le fichier existe déjà, sysopen échoue. Si le fichier nommé par NOM_FICHIER n'existe pas et que le MODE inclut le flag O_CREAT, alors sysopen crée le fichier avec les permissions initiales déterminées par l'argument MASQUE (ou 0666 s'il est omis) et modifié par le umask courant de votre processus. Cette valeur par défaut est raisonnable : voir la définition de umask pour une explication.

Les handles de fichiers ouverts avec open et sysopen peuvent être utilisés de manière interchangeable. Vous n'avez pas besoin d'utiliser sysread et ses amis simplement parce que vous avez ouvert le fichier avec sysopen, et rien ne vous en empêche si vous l'avez ouvert avec open. Les deux sont capables de choses que l'autre ne peut pas faire. Un open traditionnel peut ouvrir des pipes, forker des processus, positionner des disciplines, dupliquer des handles de fichiers et convertir un numéro descripteur de fichier vers un handle de fichier. De plus, il ignore les caractères d'espacement au début ou à la fin du nom de fichier et respecte la particularité de « - » en tant que nom de fichier spécial. Mais lorsqu'il s'agit d'ouvrir de véritables fichiers, sysopen peut faire tout ce qu'open fait.

Les exemples suivants montrent les appels équivalents à ces deux fonctions. Nous avons omis les vérifications or die $! pour plus de clarté, mais assurez-vous de toujours vérifier les valeurs de retour dans vos programmes. Nous nous restreindrons à n'employer que les flags disponibles sur virtuellement tous les systèmes d'exploitation. Il s'agit simplement d'un moyen de contrôler les valeurs que vous rassemblez par un OU en utilisant l'opérateur de bit | pour les passer dans l'argument MODE .

  • Ouvrir un fichier en lecture :
 
Sélectionnez
open(HF, "<", $chemin);
sysopen(HF, $chemin, O_RDONLY);
  • Ouvrir un fichier en écriture, en créant un nouveau fichier si besoin ou en tronquant un fichier existant :
 
Sélectionnez
open(HF, ">", $chemin);
sysopen(HF, $chemin, O_WRONLY | O_TRUNC | O_CREAT);
  • Ouvrir un fichier en ajout, en le créant si besoin :
 
Sélectionnez
open(HF, ">>", $chemin);
sysopen(HF, $chemin, O_WRONLY | O_APPEND | O_CREAT);
  • • Ouvrir un fichier en mise à jour, le fichier devant déjà exister :
 
Sélectionnez
open(HF, "+<", $chemin);
sysopen(HF, $chemin, O_RDWR);

Et voici ce que vous pouvez faire avec, sysopen mais pas avec un open traditionnel :

  • Ouvrir et créer un fichier en écriture, le fichier ne devant pas déjà exister :
 
Sélectionnez
sysopen(HF, $chemin, O_WRONLY | O_EXCL | O_CREAT);
  • Ouvrir un fichier en ajout, le fichier devant déjà exister :
 
Sélectionnez
sysopen(HF, $chemin, O_WRONLY | O_APPEND);
  • Ouvrir un fichier en mise à jour, en créant un nouveau fichier si besoin :
 
Sélectionnez
sysopen(HF, $chemin, O_RDWR | O_CREAT);
  • Ouvrir un fichier en mise à jour, le fichier ne devant pas déjà exister :
 
Sélectionnez
sysopen(HF, $chemin, O_RDWR | O_EXCL | O_CREAT);
  • Ouvrir un fichier en écriture seule sans bloquer, mais sans créer le fichier s'il n'existe pas :
 
Sélectionnez
sysopen(HF, $chemin, O_WRONLY | O_NONBLOCK);

Le module FileHandle, décrit au chapitre 32, offre un ensemble de synonymes orientés objet (plus quelques nouvelles fonctionnalités) pour ouvrir des fichiers. Vous êtes cordialement invités à utiliser les méthodes appropriées de FileHandle(216) sur tout handle créé avec open, sysopen, pipe, socket ou accept, même si vous n'avez pas employé le module pour initialiser ces handles.

sysread Image non disponible Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
sysread HANDLE_FICHIER, SCALAIRE, LONGUEUR, DECALAGE
sysread HANDLE_FICHIER, SCALAIRE, LONGUEUR

Cette fonction tente de lire LONGUEUR octets de données dans la variable SCALAIRE depuis le HANDLE_FICHIER spécifié en utilisant l'appel système de bas niveau read(2). La fonction renvoie le nombre d'octets réellement lus, ou 0 en fin de fichier. Elle renvoie undef en cas d'erreur. La taille de SCALAIRE sera ajustée à la longueur effectivement lue. Le DECALAGE, s'il est spécifié, indique à partir d'où lire dans la chaîne, afin de pouvoir lire au milieu d'une chaîne utilisée comme tampon. Voir syswrite pour un exemple d'utilisation de DECALAGE. Une exception est levée si LONGUEUR est négative ou si DECALAGE pointe à l'extérieur de la chaîne.

Préparez-vous à gérer vous-même les problèmes (comme les appels système interrompus) que les entrées/sorties standards gèrent habituellement pour vous. Comme sysread passe outre les entrées/sorties standards, ne mélangez pas sysread avec d'autres types de lectures, ni avec print, printf, write, seek, tell ou eof à moins d'être adepte des sciences occultes (ou des soirées cuir et chaînes). De même, soyez s'il vous plaît prévenus que lors de la lecture dans un fichier contenant de l'Unicode ou tout autre encodage sur plusieurs octets, les frontières du tampon peuvent tomber au milieu d'un caractère.

sysseek Image non disponible Image non disponible

 
Sélectionnez
sysseek HANDLE_FICHIER, POSITION, DEPART

Cette fonction affecte la position système du HANDLE_FICHIER en utilisant l'appel système lseek(2). Elle passe outre les entrées/sorties standard, ainsi les mélanges avec des lectures (autres que par sysread), ou avec print, printf, write, seek, tell ou eof peuvent semer la confusion. HANDLE_FICHIER peut être une expression dont la valeur donne le nom du handle de fichier. Les valeurs de DEPART sont 0 pour mettre se positionner exactement à POSITION, 1 pour se positionner à la position courante plus POSITION et 2 pour se positionner à EOF plus POSITION (en général, négative). Pour DEPART, vous pouvez utiliser les constantes SEEK_SET, SEEK_CUR et SEEK_END des modules standards IO::Seekable et POSIX — ou, depuis la version 5.6 de Perl, du module Fcntl qui est plus portable et plus pratique.

La fonction renvoie la nouvelle position ou undef en cas d'échec. Une position de zéro est renvoyée comme étant la chaîne spéciale « 0 but true » (N.d.T. : 0, mais vrai), qui peut être utilisée numériquement sans produire d'avertissements.

system Image non disponible Image non disponible Image non disponible

 
Sélectionnez
system CHEMIN LISTE
system CHEMIN

Cette fonction exécute pour vous tout programme existant sur le système et renvoie le code de retour de ce programme — et non sa sortie. Pour capturer la sortie d'une commande, utilisez les apostrophes inverses ou qx// à la place. La fonction system fonctionne exactement comme exec, hormis le fait qu'elle effectue d'abord un fork puis, qu'après l'exec, elle attende que le programme exécuté se termine. C'est-à-dire qu'elle lance le programme et revient quand ce dernier a fini, au contraire d'exec, qui remplace le programme en train de tourner par le nouveau et qui donc ne revient jamais si le remplacement réussit.

Le traitement des paramètres varie selon le nombre d'arguments, comme dans la description d'exec, y compris le fait de déterminer si le shell sera appelé et si vous avez menti au programme à propos de son nom en spécifiant un CHEMIN séparé.

Étant donné que system et les apostrophes inverses bloquent les signaux SIGINT et SIGQUIT, l'envoi de l'un de ces signaux (provenant par exemple d'un Control-C) au programme en train de tourner n'interrompt pas votre programme principal. Mais l'autre programme qui est en train de tourner reçoit bien le signal. Vérifiez la valeur de retour de system pour voir si le programme que vous avez lancé s'est terminé proprement ou pas.

 
Sélectionnez
@args = ("commande", "arg1", "arg2");
system(@args) == 0
    or die "system @args a échoué : $?";

La valeur de retour est le statut de sortie du programme tel que renvoyé par l'appel système wait(2). Avec les sémantiques traditionnelles, pour obtenir la véritable valeur de sortie, divisez par 256 ou faites un décalage de 8 bits vers la gauche. Ceci, car l'octet de poids faible contient quelque chose d'autre. (Deux choses en fait.) Les sept bits de poids faible indiquent le numéro du signal qui a tué le processus (s'il y en a un) et le huitième bit indique si le processus a fait une copie du cœur du programme (core dump). Vous pouvez vérifier toutes les possibilités d'échec, y compris les signaux et les core dumps, en inspectant $? ($CHILD_ERROR) :

 
Sélectionnez
$valeur_sortie = $? >>  8;
$num_signal    = $? & 127;   # ou 0x7f, ou 0177, ou 0b0111_1111
$coeur_copie   = $? & 128;   # ou 0x80, ou 0200, ou 0b1000_0000

Lorsque le programme a été lancé à travers un shell(217) car vous aviez un seul argument et que cet argument contenait des métacaractères du shell, les codes de retours normaux sont sujets aux caprices et aptitudes supplémentaires du shell. En d'autres termes, dans ces circonstances, vous pouvez être incapable de retrouver l'information détaillée décrite précédemment.

syswrite Image non disponible Image non disponible Image non disponible

 
Sélectionnez
syswrite HANDLE_FICHIER, SCALAIRE, LONGUEUR, DECALAGE
syswrite HANDLE_FICHIER, SCALAIRE, LONGUEUR
syswrite HANDLE_FICHIER, SCALAIRE

Cette fonction tente d'écrire LONGUEUR octets de données depuis la variable SCALAIRE vers le HANDLE_FICHIER spécifié en utilisant l'appel système write(2). La fonction renvoie le nombre d'octets réellement écrits, ou undef en cas d'erreur. Le DECALAGE, s'il est spécifié, indique à partir de quel endroit de la chaîne il faut commencer à écrire. (Si par exemple la chaîne vous sert par exemple de tampon, ou qu'il vous faut reprendre une écriture partielle.) Un DECALAGE négatif spécifie que l'écriture doit partir de ce nombre d'octets depuis la fin de la chaîne. Si SCALAIRE est vide, le seul DECALAGE permis est 0. Une exception est levée si LONGUEUR est négative ou si DECALAGE pointe à l'extérieur de la chaîne.

Pour copier des données du handle de fichier DEPUIS vers le handle de fichier VERS, vous pouvez utiliser quelque chose comme :

 
Sélectionnez
use Errno qw/EINTR/;
$taille_bloc = (stat FROM)[11] ||16384; # taille de bloc préférée ?
while ($lng = sysread DEPUIS, $tamp, $taille_bloc) {
    if (!defined $lng) {
        next if $! == EINTR;
        die "Erreur système sur read : $!\n";
    }
    $decalage = 0;
    while ($lng) {   # Gère les écritures partielles.
        $ecrit = syswrite VERS, $tamp, $lng, $decalage;
        die "Erreur système sur write : $!\n" unless defined $ecrit;
        $decalage += $ecrit;
        $lng -= $ecrit;
    }
}

Préparez-vous à gérer par vous-même les problèmes que les entrées/sorties standards traitent habituellement pour vous, telles que les écritures partielles. Comme syswrite passe outre les entrées/sorties standards de la bibliothèque C, ne mélangez pas d'appels à syswrite avec des lectures (autres que sysread), des écritures (comme print, printf ou write) ou d'autres opérations d'entrées/sorties comme seek, tell ou eof à moins d'être adepte des sciences occultes.(218)

tell Image non disponible

 
Sélectionnez
tell HANDLE_FICHIER
tell

Cette fonction renvoie la position actuelle dans le fichier (en octets, sur une base de zéro) pour HANDLE_FICHIER. Généralement, cette valeur est passée à la fonction seek à un moment ultérieur pour revenir à la position courante. HANDLE_FICHIER peut être une expression donnant le nom du handle de fichier réel ou une référence sur un objet handle de fichier. Si HANDLE_FICHIER est omis, la fonction renvoie la position dans le dernier fichier lu. Les positions ne sont significatives que sur les fichiers ordinaires. Les périphériques, les pipes et les sockets ne connaissent pas les positions.

Il n'existe pas de fonction systell. Utilisez sysseek(HF, 0, 1) pour cela. Voir seek pour un exemple expliquant comment utiliser tell.

telldir Image non disponible Image non disponible

 
Sélectionnez
telldir HANDLE_REPERTOIRE

Cette fonction renvoie la position courante des routines readdir sur HANDLE_REPERTOIRE. Cette valeur peut être fournie à seekdir pour accéder à un endroit particulier d'un répertoire. La fonction comporte les mêmes dangers relatifs à un possible compactage du répertoire que la routine de la bibliothèque système correspondante. Cette fonction peut ne pas être implémentée partout où l'est readdir. Même si c'est le cas, aucun calcul ne peut être fait avec la valeur de retour. Il s'agit seulement d'une valeur opaque, qui n'a de signification que pour seekdir.

tie Image non disponible

 
Sélectionnez
tie VARIABLE, NOM_CLASSE, LISTE

Cette fonction relie une variable à une classe de paquetage qui fournit l'implémentation de la variable. VARIABLE est la variable (scalaire, tableau ou hachage) ou le type glob (représentant un handle de fichier) qui doit être relié. NOM_CLASSE est le nom d'une classe implémentant des objets du type approprié.

Tous les arguments additionnels sont passés à la méthode constructeur appropriée, soit l'un des constructeurs parmi TIESCALAR, TIEARRAY ou TIEHASH. (Si la méthode appropriée n'est pas trouvée, une exception est levée.) Ces arguments sont généralement similaires à ceux que l'on enverrait à la fonction dbm_open(3) du C, mais leur signification dépend du paquetage. L'objet renvoyé par le constructeur est à son tour renvoyé par la fonction tie, ce qui s'avère utile si vous voulez accéder à d'autres méthodes de NOM_CLASSE. (On peut aussi accéder à l'objet par le biais de la fonction tied). Ainsi, une classe reliant un hachage à une implémentation ISAM peut fournir une méthode supplémentaire pour traverser séquentiellement un ensemble de clefs (le « S » de ISAM), puisque vos implémentations habituelles de DBM ne peuvent pas le faire.

Les fonctions comme keys et values peuvent renvoyer d'énormes valeurs de listes quand elles sont appliquées à de grands objets comme des fichiers DBM. Vous pouvez préférer utiliser la fonction each pour parcourir ces derniers. Par exemple :

 
Sélectionnez
use NDBM_File;
tie %ALIAS, "NDBM_File", "/etc/aliases", 1, 0
    or die "Impossible d'ouvrir les alias : $!\n";
while (($clef,$val) = each %ALIAS) {
    print $clef, ' = ', $val, "\n";
}
untie %ALIAS;

Une classe implémentant un hachage doit comprendre les méthodes suivantes :

 
Sélectionnez
TIEHASH CLASSE, LISTE
FETCH SOI, CLEF
STORE SOI, CLEF, VALEUR
DELETE SOI, CLEF
CLEAR SOI
EXISTS SOI, CLEF
FIRSTKEY SOI
NEXTKEY SOI, CLEF_PRECEDENTE
DESTROY SOI

Une classe implémentant un tableau ordinaire doit comprendre les méthodes suivantes :

 
Sélectionnez
TIEARRAY CLASSE, LISTE
FETCH SOI, INDICE
STORE SOI, INDICE, VALEUR
FETCHSIZE SOI
STORESIZE SOI, COMPTEUR
CLEAR SOI
PUSH SOI, LISTE
POP SOI
SHIFT SOI
UNSHIFT SOI LISTE
SPLICE SOI, DECALAGE, LONGUEUR, LISTE
EXTEND SOI, COMPTEUR
DESTROY SOI

Une classe implémentant un scalaire doit comprendre les méthodes suivantes :

 
Sélectionnez
TIESCALAR CLASSE, LISTE
FETCH SOI
STORE SOI, VALEUR
DESTROY SOI

Une classe implémentant un handle de fichier doit comprendre les méthodes suivantes :

 
Sélectionnez
TIEHANDLE CLASSE, LISTE
READ SOI, SCALAIRE, LONGUEUR, DECALAGE
READLINE SOI
GETC SOI
WRITE SOI, SCALAIRE, LONGUEUR, DECALAGE
PRINT SOI, LISTE
PRINTF SOI, FORMAT, LISTE
CLOSE SOI
DESTROY SOI

Les méthodes indiquées ci-dessus n'ont pas toutes besoin d'être implémentées : Les modules Tie::Hash, Tie::Array, Tie::Scalar et Tie::Handle fournissent des classes de base qui ont des méthodes par défaut raisonnables. Voir chapitre 14, Variables attachées, pour un commentaire détaillé de ces méthodes. À l'inverse de dbmopen, la fonction tie ne fera pas automatiquement un use ou un require — vous devez le faire vous-même explicitement. Voir les modules DB_File et Config qui fournissent des implémentations intéressantes de tie.

tied

 
Sélectionnez
tied VARIABLE

Cette fonction renvoie une référence vers l'objet qui sous-tend le scalaire, le tableau, le hachage ou le typeglob contenu dans VARIABLE (la même valeur qui a été renvoyée à l'origine par l'appel à tie, qui a lié la variable au paquetage). Elle renvoie la valeur indéfinie si VARIABLE n'est pas attachée à un paquetage. Vous pouvez par exemple utiliser :

 
Sélectionnez
ref tied %hachage

pour savoir à quel paquetage votre hachage est attaché. (À supposer que vous l'ayez oublié).

time

 
Sélectionnez
time

Cette fonction renvoie le nombre de secondes écoulées depuis le 1er janvier 1970, UTC, à 00::00::00.(219) La valeur renvoyée est acceptée par gmtime et localtime pour servir aux comparaisons avec les dates de modification et d'accès renvoyées par stat et pour être passée à utime.

 
Sélectionnez
$debut = time(); system("une commande lente");
$fin = time();
if ($fin - $debut > 1) {
    print "Le programme a commencé à : ", scalar localtime($debut), "\n";
    print "Le programme a fini à :     ", scalar localtime($fin), "\n";
}

times Image non disponible

 
Sélectionnez
times

Dans un contexte de liste, cette fonction renvoie un tableau à quatre éléments donnant les temps utilisateur et système, en secondes (probablement fractionnaires), pour ce processus et pour les fils de ce processus qui sont terminés.

 
Sélectionnez
($utilisateur, $systeme, $cutilisateur, $csysteme) = times();
printf "Ce pid et ses fils ont consommé %.3f secondes\n",
    $utilisateur + $systeme + $cutilisateur + $csysteme;

Dans un contexte scalaire, elle ne renvoie que le temps utilisateur. Par exemple, pour mesurer la vitesse d'exécution d'une section de code Perl :

 
Sélectionnez
$debut = times();
...
$fin = times();
printf "Nous avons mis %.2f secondes CPU en temps utilisateur\n",
        $fin - $debut;

tr/// Image non disponible

 
Sélectionnez
tr///
y///

Il s'agit de l'opérateur de traduction (appelé aussi translation), qui ressemble à l'opérateur y/// du programme sed d'UNIX, en mieux, selon l'humble opinion de tout le monde. Voir le chapitre 5.

truncate Image non disponible Image non disponible Image non disponible Image non disponible

 
Sélectionnez
truncate HANDLE_FICHIER, LONGUEUR
truncate EXPR, LONGUEUR

Cette fonction tronque le fichier ouvert sur HANDLE_FICHIER, ou nommé par EXPR, à la longueur spécifiée. La fonction lève une exception si truncate(2) ou un équivalent n'est pas implémenté sur le système. (Il est toujours possible de tronquer un fichier en n'en recopiant que le début, si vous disposez de l'espace disque nécessaire.) La fonction renvoie vrai en cas de succès, undef sinon.

uc Image non disponible Image non disponible

 
Sélectionnez
uc EXPR
uc

Cette fonction renvoie une version en majuscules de EXPR. Il s'agit de la fonction interne implémentant l'échappement \U dans les chaînes entre guillemets. Perl essayera de faire de qu'il faut pour respecter les valeurs actuelles de votre locale, mais nous travaillons toujours sur les interactions avec Unicode. Voir la page de manuel perllocale pour les dernières avancées. Dans tous les cas, lorsque Perl utilise les tables Unicode, uc convertit en majuscules plutôt qu'en capitales de titres. Voir ucfirst pour les conversions en capitales de titres.

ucfirst Image non disponible Image non disponible

 
Sélectionnez
ucfirst EXPR
ucfirst

Cette fonction renvoie une version de EXPR avec la première lettre en majuscule (titlecased, mise en capitale de titre dans le jargon Unicode). Il s'agit de la fonction interne implémentant l'échappement \u dans les chaînes entre guillemets. Votre locale LC_CTYPE actuelle peut être respectée si vous faites un use locale et si vos données ne ressemblent pas à de l'Unicode, mais nous ne garantissons rien pour le moment.

Pour forcer la première lettre en capitale et tout le reste en minuscules, utilisez :

 
Sélectionnez
ucfirst lc $mot

ce qui est équivalent à "\u\L$mot".

umask Image non disponible Image non disponible

 
Sélectionnez
umask EXPR
umask

Cette fonction fixe le umask (masque utilisateur) du processus et renvoie l'ancien en utilisant l'appel système umask(2). Votre umask indique au système d'exploitation quels bits de permissions désactiver au moment de créer un nouveau fichier, y compris les fichiers qui sont des répertoires. Si EXPR est omise, la fonction se contente de renvoyer le umask courant. Par exemple, pour s'assurer que les bits « utilisateur » sont activés et que les bits « autres » sont désactivés, essayez quelque chose comme :

 
Sélectionnez
umask((umask() & 077) | 7);   # ne change pas les bits "groupe"

Rappelez-vous qu'un umask est un nombre, habituellement donné en octal ; ce n'est pas une chaîne de chiffres octaux. Voir aussi oct, si tout ce que vous avez est une chaîne. Rappelez-vous également que les bits d'umask sont le complément des permissions ordinaires.

Les permissions Unix rwxr-x--- sont représentées comme trois ensembles de trois bits, ou trois chiffres octaux : 0750 (le 0 du début indique un octal et ne compte pas comme un des chiffres). Puisque les bits d'umask sont complémentaires, ils représentent des bits de permissions désactivées. Les valeurs de permission (ou « mode ») que vous fournissez à mkdir ou sysopen sont modifiés par votre umask, ainsi même si vous dites à sysopen de créer un fichier avec les permissions 0777, si votre umask vaut 0022, le fichier est créé avec les permissions 0755. Si votre umask valait 0027 (le groupe ne peut pas écrire, les autres ne peuvent ni lire, ni écrire, ni exécuter), alors passer à sysopen un MASQUE de 0666 créerait un fichier avec un mode de 0640 (puisque 0666 & ~0027 vaut 0640).

Voici quelques conseils : donnez un mode de création valant 0666 pour les fichiers normaux (pour sysopen) et un de 0777 à la fois pour les répertoires (pour mkdir) et pour les fichiers exécutables. Cela donne aux utilisateurs la liberté de choisir : s'ils veulent des fichiers protégés, ils choisiront des umasks de processus de 022, 027 ou même le masque particulièrement antisocial de 077. Les programmes ne doivent que rarement, si ce n'est jamais, prendre des décisions stratégiques qu'il vaut mieux laisser à l'utilisateur. Les exceptions à cette règle sont les programmes qui écrivent des fichiers qui doivent rester privés : fichiers mails, cookies de navigateurs web, fichiers .rhosts, et ainsi de suite.

Si umask(2) n'est pas implémenté sur votre système et que vous essayez de restreindre votre propre accès (c'est-à-dire, si (EXPR & 0700) > 0), vous déclencherez une exception à l'exécution. Si umask(2) n'est pas implémenté sur votre système et que vous n'essayez pas de restreindre votre propre accès, la fonction renverra simplement undef.

undef Image non disponible

 
Sélectionnez
undef EXPR
undef

undef est le nom sous lequel nous nous référons à l'abstraction connue sous le nom de la valeur indéfinie. Il se trouve aussi qu'il s'agit d'une fonction bien nommée qui renvoie toujours la valeur indéfinie. Nous mélangeons les deux avec joie.

Par coïncidence, la fonction undef rend explicitement indéfinie une entité si vous passez son nom comme argument. L'argument EXPR, s'il est spécifié, soit être une lvalue. À partir de là, vous ne pouvez utiliser qu'une valeur scalaire, un tableau complet, un hachage complet, un nom de sous-programme (en utilisant le préfixe &) ou un typeglob. Toute la mémoire associée à l'objet sera récupérée (mais pas renvoyée au système, pour la plupart des systèmes d'exploitation). La fonction undef ne fera probablement pas ce que vous attendez d'elle sur la plupart des variables spéciales. L'utiliser sur des variables en lecture seule, comme $1, lève une exception.

La fonction undef est un opérateur unaire, non un opérateur de liste, vous ne pouvez donc rendre indéfini qu'une seule chose à la fois. Voici quelques exemples d'utilisation d'undef en tant qu'opérateur unaire :

 
Sélectionnez
undef $bidule;
undef $machin{'truc'};  # Différent de delete $machin{'truc'};
undef @tableau
undef %hachage;
undef &monsp;
undef *xyz              # Détruit $xyz, @xyz, %xyz, &xyz, etc.

Sans son argument, undef n'est utilisé que pour sa valeur :

 
Sélectionnez
select(undef, undef, undef, $sieste);

return (wantarray ? () : undef) if $dans_les_choux;
return if $dans_les_choux; # même chose

Vous pouvez utiliser undef comme un emplacement dans la partie gauche d'une affectation de liste, auquel cas la valeur correspondante de la partie droite est simplement rejetée. À part cela, vous ne pouvez pas utiliser undef en tant que lvalue.

 
Sélectionnez
($a, $b, undef, $c) = &truc; # Ignore la troisième valeur renvoyée

De plus, n'essayez pas de comparer quoi que ce soit avec undef — ça ne fait pas ce que vous pensez. Tout ce que ça fait, c'est comparer avec 0 ou la chaîne vide. Utilisez la fonction defined pour déterminer si une valeur est définie.

unlink Image non disponible Image non disponible Image non disponible

 
Sélectionnez
unlink LISTE
unlink

Cette fonction supprime une liste de fichiers.(220) La fonction renvoie le nombre de fichiers effectivement supprimés. Quelques exemples simples :

 
Sélectionnez
$cpt = unlink 'a', 'b', 'c';
unlink @partants;
unlink glob("*.orig");

La fonction unlink ne supprime pas les répertoires à moins d'être super-utilisateur et que l'option de la ligne de commande -U soit donnée à Perl. Même dans ces conditions, vous êtes prévenus que l'effacement d'un répertoire est susceptible d'infliger des dommages sévères dans votre système de fichiers. Employez plutôt rmdir.

Voici une commande rm très simple avec une vérification d'erreurs qui ne l'est pas moins :

 
Sélectionnez
#!/usr/bin/perl
@impossible = grep {not unlink}, @ARGV;
die "$0: unlink de @impossible impossible\n" if @impossible;

unpack Image non disponible

 
Sélectionnez
unpack CANEVAS, EXPR

Cette fonction fait l'inverse de pack : elle développe une chaîne (EXPR) représentant une structure de données et l'éclate selon le CANEVAS en une liste de valeurs qu'elle renvoie. Dans un contexte scalaire, elle peut être employée pour dépaqueter une seule valeur. Le CANEVAS est ici à peu près du même format que pour la fonction pack -il spécifie l'ordre et le type des valeurs à dépaqueter. Voir pack pour une description plus détaillée de CANEVAS. Un élément invalide dans le CANEVAS ou une tentative déplacement à l'extérieur de la chaîne avec les formats x, X ou @, lève une exception.

La chaîne est découpée en morceaux décrits dans le CANEVAS. Chaque morceau est converti séparément en une valeur. Généralement, les octets de la chaîne sont le résultat d'un pack ou ils représentent une structure C d'un certain type.

Si le compteur de répétitions d'un champ est plus grand que ce que le reste dans la chaîne en entrée le permet, le compteur de répétitions est décrémenté en douce. (Normalement, vous devriez de toute façon utiliser un compteur de répétitions valant ici *.) Si la chaîne en entrée est plus grande que ce que décrit le CANEVAS, le reste de la chaîne est ignoré.

La fonction unpack est également très utile pour les données de texte brut, pas seulement pour les données binaires. Supposez que vous ayez un fichier de données qui contiendrait des enregistrements ressemblant à ceci :

 
Sélectionnez
2000 Ingrid Caven                   Jean-Jacques Schuhl
1999 Première ligne                 Jean-Marie Laclavetine
1998 Confidence pour confidence     Paule Constant
1997 La bataille                    Patrick Rambaud
1996 Le chasseur Zéro               Roze Pascale
1995 Le testament français          André Makine
1994 Un aller simple                Didier Van Cauwelaert
1993 Le rocher de Tanios            Amin Maalouf
1992 Texaco                         Patrick Chamoiseau

vous ne pouvez pas utiliser split pour décomposer les champs, car ils n'ont pas de séparateur distinct. À la place, les champs sont déterminés par leur décalage d'octets dans l'enregistrement. Ainsi même s'il s'agit d'un enregistrement de texte ordinaire, puisqu'il est composé dans un format fixe, vous pouvez utiliser unpack pour le décomposer :

 
Sélectionnez
while (<>) {
    ($annee, $titre, $auteur) = unpack("A4 x A26 A*", $_);
    print "$auteur a gagné le prix Goncourt $annee pour $titre\n";
}

Voici un programme uudecode complet :

 
Sélectionnez
#!/usr/bin/perl
$_ = <>
until ($mode,$fichier) = /^begin\s*(\d*)\s*(\S*)/;
open(SORTIE,"> $fichier") if $fichier ne "";
while (<>) {
    last if /^end/;
    next if /[a-z]/;
    next unless int((((ord() - 32) & 077) + 2) / 3) ==
                int(length() / 4);
    print SORTIE unpack "u", $_;
}
chmod oct $mode, $fichier;

En plus des champs autorisés dans pack, vous pouvez préfixer un champ par %nombre pour produire une somme de contrôle des entités sur nombre bits au lieu des entités elles-mêmes. La valeur par défaut est une somme de contrôle de 16 bits. La somme de contrôle est calculée en additionnant les valeurs numériques des valeurs développées (pour les champs de chaînes, on additionne ord($,car) et pour les champs de bits, on additionne les zéros et les uns). Par exemple, ce qui suit calcule le même nombre que le programme sum(1) de System V :

 
Sélectionnez
undef $/;
$somme_controle = unpack ("%32C*", <>) % 65536;

L'exemple suivant compte de façon efficace le nombre de bits positionnés dans un vecteur de bits :

 
Sélectionnez
$bits_a_1 = unpack "%32b*", $masque_de_select;

Voici un décodeur simple MIME (BASE 64) :

 
Sélectionnez
while (<>) {
    tr#A-Za-z0-9+/##cd;                 # enlever les caractères non-base 64
    tr#A-Za-z0-9+/# -_#;                # convertir au format uuencodé
    $lng = pack("c", 32 + 0.75*length); # calculer l'octet de longueur
    print unpack("u", $len . $_);       # uudécoder et afficher
}

unshift

 
Sélectionnez
unshift TABLEAU, LISTE

Cette fonction fait l'inverse de shift. (Ou l'inverse de push, selon le point de vue.) Elle ajoute une LISTE au début du tableau et renvoie le nombre actualisé d'éléments dans le tableau :

 
Sélectionnez
unshift @ARGV, '-e', $cmd unless $ARGV[0] =~ /^-/;

Remarquez que la LISTE est ajoutée en entier au début, et non un élément à la fois, les éléments ajoutés au début restent donc dans le même ordre. Utilisez reverse pour les inverser.

untie

 
Sélectionnez
untie VARIABLE

Brise le lien existant entre une variable ou un typeglob contenu dans VARIABLE et le paquetage auquel elle était liée. Voir tie et l'intégralité du chapitre 14, mais tout particulièrement la section Un piège subtil du déliement.

use Image non disponible Image non disponible

 
Sélectionnez
use MODULE VERSION LISTE
use MODULE VERSION ()
use MODULE VERSION
use MODULE LISTE
use MODULE ()
use MODULE
use VERSION

La déclaration use charge un module, s'il n'a pas déjà été chargé auparavant, et importe depuis ce module des sous-programmes et des variables dans le paquetage courant. (En langage technique, elle importe depuis le module donné des sémantiques dans votre paquetage.) La plupart des déclarations use ressemblent à :

 
Sélectionnez
use MODULE LISTE;

Ce qui est exactement équivalent à :

 
Sélectionnez
BEGIN { require MODULE ; import MODULE LISTE ;}

Le BEGIN force le require et le import à se produire au moment de la compilation. Le require s'assure que le module est chargé en mémoire s'il ne l'est pas déjà. L'import n'est pas une fonction interne — c'est simplement un appel ordinaire de méthode dans le package nommé par MODULE pour demander à ce module de mettre la liste des fonctionnalités dans le package courant. Le module peut implémenter sa méthode d'importation de la manière qui lui plaît, bien que la plupart choisissent simplement de dériver leur méthode d'importation par héritage de la classe Exporter qui est définie dans le module Exporter. Voir le chapitre 11, Modules et le module Exporter pour plus d'informations. Si aucune méthode import ne peut être trouvée, l'appel est abandonné sans un mot.

Si vous ne voulez pas altérer votre espace de nom, fournissez explicitement une liste vide :

 
Sélectionnez
use MODULE ();

Ce qui est exactement équivalent à :

 
Sélectionnez
BEGIN { require MODULE ;}

Si le premier argument de use est un numéro de version comme 5.6.2, la version courante de Perl en train de s'exécuter doit être au moins aussi récente que la version spécifiée. Si la version actuelle de Perl est inférieur à VERSION, un message d'erreur est affiché et l'interpréteur Perl se termine immédiatement. Ceci est très utile pour vérifier la version courante de Perl avant de charger des modules de bibliothèque qui dépendent des nouvelles versions, puisque de temps en temps, nous avons besoin de « casser » les mauvaises fonctionnalités des anciennes versions de Perl. (Nous n'essayons pas de casser plus de choses que nécessaire. En fait nous essayons souvent de casser moins de choses que nécessaire.)

Et puisque nous parlons de ne pas casser certaines choses, Perl accepte encore les anciens numéros de versions de la forme :

 
Sélectionnez
use 5.005_03;

Toutefois, pour mieux s'aligner avec les standards de l'industrie, Perl 5.6 accepte désormais (et nous préférons voir) la syntaxe sous forme d'un triplet :

 
Sélectionnez
use 5.6.0;  # Soit, version 5, sous-version 6, correctif 0.

Si l'argument VERSION est présent après MODULE, alors le use appellera la méthode VER-SION de la classe MODULE avec la VERSION donnée comme argument. Remarquez qu'il n'y a pas de virgule après VERSION ! La méthode VERSION par défaut, qui est héritée de la classe UNIVERSAL, meurt en gémissant si la version donnée est plus élevée que la valeur de la variable $Module::VERSION.

Voir le chapitre 32 pour une liste des modules standards.

Comme use fournit une interface largement ouverte, les pragmas (directives de compilation) sont également implémentés via des modules. Les pragmas actuellement implémentées comprennent :

 
Sélectionnez
use autouse 'Carp' => qw(carp croak);
use bytes;
use constant PI => 4 * atan2(1,1);
use diagnostics;
use integer;
use lib '/opt/projets/spectre/lib';
use locale;
use sigtrap qw (die INT QUIT);
use strict qw(subs vars refs);
use warnings "deprecated";

La plupart de ces modules pragmatiques importent des définitions dans la portée lexicale courante. (Au contraire des modules ordinaires, qui n'importent des symboles que dans le paquetage courant, qui a un rapport minime avec la portée lexicale courante autre que le fait que la portée lexicale est compilée avec ce paquetage à l'esprit. Ceci pour dire que. . . oh et puis zut, voyez le chapitre 11.)

Il existe une déclaration correspondante, no, qui « désimporte » toutes les significations importées à l'origine avec use qui sont devenues depuis, heu, sans importance :

 
Sélectionnez
no integer;
no strict 'refs';
no utf8;
no warnings "unsafe";

Voir le chapitre 31 pour une liste des pragmas standards.

utime Image non disponible Image non disponible Image non disponible

 
Sélectionnez
utime LISTE

Cette fonction change les dates d'accès et de modification sur chacun des fichiers de la liste. Les deux premiers éléments de la liste doivent être les dates d'accès et de modification en numérique, dans cet ordre. La fonction renvoie le nombre de fichiers changés avec succès. La date de modification d'inode de chaque fichier est fixée à la date courante. Voici un exemple d'une commande touch qui met la date de modification du fichier (en supposant que vous en êtes le propriétaire) à environ un mois dans le futur :

 
Sélectionnez
#!/usr/bin/perl
# touch_mois -antidate les fichiers à maintenant + 1 mois
$jour = 24 * 60 * 60;               # 24 heures en secondes
$plus_tard = time() + 30 * $jour;   # 30 jours, c'est environ un mois
utime $plus_tard, $plus_tard, @ARGV;

et voici un exemple un peu plus sophistiqué d'une commande qui fait un touch avec quelques notions de contrôle d'erreurs :

 
Sélectionnez
#!/usr/bin/perl
# touch_mois -antidate les fichiers à maintenant + 1 mois
$plus_tard = time() + 30 * 24 * 60 * 60;
@impossibles = grep {not utime $plus_tard, $plus_tard, $_} @ARGV;
die "touch impossible de @impossibles.\n" if @impossibles;

Pour lire les dates de fichiers existants, utilisez stat et passez les champs appropriés à localtime ou gmtime pour l'affichage.

values

 
Sélectionnez
values HACHAGE

Cette fonction renvoie une liste constituée de toutes les valeurs du HACHAGE indiqué. Les valeurs sont renvoyées dans un ordre apparemment aléatoire, mais c'est le même que celui produit par les fonctions keys ou each pour le même hachage. Curieusement, pour trier un hachage par ses valeurs, vous aurez besoin habituellement de la fonction keys, regardez donc l'exemple dans la description de keys.

Vous pouvez modifier les valeurs d'un hachage en utilisant cette fonction, car la liste renvoyée contient des alias des valeurs et pas simplement des copies. (Dans les versions précédentes, vous aviez besoin d'utiliser pour ce faire une portion de hachage.)

 
Sélectionnez
for (@hachage{keys %hachage}) { s/machin/truc/g } # ancienne manière
for (values %hachage)         { s/machin/truc/g } # modifie maintenant
                                                  # les valeurs

L'emploi de values sur un hachage lié à un fichier DBM important est voué à produire une liste tout aussi volumineuse, ce qui vous donnera un processus important. Il peut être préférable pour vous d'utiliser dans ce cas la fonction each, qui parcourra les entrées de hachage une à une, sans les absorber en une liste gargantuesque.

vec Image non disponible

 
Sélectionnez
vec EXPR, DECALAGE, BITS

La fonction vec fournit un stockage compact de listes d'entiers non signés. Ces entiers sont empaquetés et compressés autant que possible dans une chaîne Perl ordinaire. La chaîne dans EXPR est traitée comme une chaîne de bits construite à partir d'un nombre arbitraire d'éléments selon la longueur de la chaîne.

DECALAGE spécifie l'indice de l'élément particulier qui vous intéresse. Les syntaxes pour lire et écrire l'élément sont les mêmes, puisque vec stocke la valeur de l'élément selon que vous utilisiez un contexte lvalue ou rvalue.

BITS spécifie l'étendue d'un élément en bits, ce qui doit être exprimé en puissance de 2 : 1, 2, 4, 8, 16 ou 32 (et également 64 sur certaines plates-formes). (Une exception est levée si une quelconque autre valeur est utilisée.) Chaque élément peut ainsi contenir un entier compris dans l'intervalle 0..(2**BITS)-1. Pour les plus petites tailles, on empaquète dans chaque octet autant d'éléments que possible. Lorsque BITS vaut 1, il y a huit éléments par octets. Lorsque BITS vaut 2, il y a quatre éléments par octets. Lorsque BITS vaut 4, il y a deux éléments (habituellement appelés des quartets) par octets. Et ainsi de suite. Les entiers plus grands qu'un octet sont stockés dans l'ordre gros-boutise (N.d.T. : big-endian).

Une liste d'entiers non signés peut être stockée dans une simple variable scalaire en les assignant individuellement à la fonction vec. (Si EXPR n'est pas une lvalue valide, une exception est levée.) Dans l'exemple suivant, les éléments font tous 4 bits de large :

 
Sélectionnez
$chaine_bits = "";
$decalage = 0;

foreach $nb (0, 5, 5, 6, 2, 7, 12, 6) {
    vec($chaine_bits, $decalage++, 4) = $num;
}

Si un élément est écrit après la fin de la chaîne, Perl étendra d'abord la chaîne avec suffisamment d'octets à zéro.

Les vecteurs stockés dans la variable scalaire peuvent par la suite être atteints en spécifiant le DECALAGE correct :

 
Sélectionnez
$nb_elements = length($chaine_bits)*2;      # 2 éléments par octet

foreach $decalage (0 .. nb_elements-1) {
    print vec($chaine_bits, $decalage, 4), "\n";
}

Si l'élément sélectionné se situe après la fin de la chaîne, une valeur de 0 est renvoyée.

Les chaînes créées avec vec peuvent également être manipulées avec les opérateurs logiques |, &, ^ et ~. Ces opérateurs postulent qu'une opération de vecteurs de bits est désirée quand les deux opérandes sont des chaînes.Voir des exemples de ceci au chapitre 3, Opérateurs unaires et binaires, dans la section Opérateurs sur les bits.

Si BITS == 1, une chaîne de bits peut être créée pour stocker une série de bits dans un seul scalaire. L'ordre est tel que l'on garantit que vec($chaine_bits,0,1) part du bit le plus faible du premier octet de la chaîne.

 
Sélectionnez
@bits = (0,0,1,0, 1,0,1,0, 1,1,0,0, 0,0,1,0);

$chaine_bits = "";
$decalage = 0;

foreach $bit (@bits) {
    vec($chaine_bits, $decalage++, 1) = $bit;
}
print "$chaine_bit\n"; # "TC", i.e. '0x54', '0x43'

Une chaîne de bits peut être convertie vers ou depuis une chaîne de 1 et de 0 en donnant un canevas de « b* » à pack ou unpack. Dans l'autre sens, pack peut être utilisé avec un canevas de « b* » pour créer la chaîne de bits depuis une chaîne de 1 et de 0. L'ordre est compatible avec celui que vec attend.

 
Sélectionnez
chaine_bits = pack "b*", join(", @bits);
print "$chaine_bits\n";          # "TC" comme précédemment

unpack peut être utilisé pour extraire la liste de 0 et de 1 de la chaîne de bits.

 
Sélectionnez
@bits = split (//, unpack("b*", $chaine_bits));
print"@bits\n";                  # 0 0 1 010 101 1 0 0 0 0 1 0

Si vous connaissez la longueur exacte en bits, celle-ci peut être utilisée en lieu et place de « * ».

Voir select pour des exemples supplémentaires d'utilisations de bitmaps générées avec vec. Voir pack et unpack pour des manipulations de données binaires à un niveau supérieur.

wait Image non disponible Image non disponible Image non disponible

 
Sélectionnez
wait

Cette fonction attend qu'un processus fils se termine et renvoie le PID du processus décédé, ou -1 s'il n'y a pas de processus fils (ou sur certains systèmes, si les processus fils sont automatiquement enterrés). Le statut est renvoyé dans $? comme nous l'avons décrit pour la fonction system. Si vous obtenez des processus fils zombies, vous devrez appeler cette fonction, ou waitpid.

S'il n'y a pas de fils, contrairement à votre attente, il s'est probablement produit un appel à system, une fermeture de pipe ou des apostrophes inverses entre le fork et le wait. Ces constructions provoquent également une attente avec wait(2) et peuvent avoir récolté votre processus fils. Utilisez waitpid pour éviter ce problème.

waitpid Image non disponible Image non disponible Image non disponible

 
Sélectionnez
waitpid PID, FLAGS

Cette fonction attend qu'un certain processus fils se termine et renvoie le PID quand le processus est mort, -1 s'il n'y a pas de fils, ou 0 si les FLAGS spécifient un appel non bloquant et que le processus n'est pas encore mort. Le statut du processus mort est renvoyé dans $? comme nous l'avons décrit pour la fonction system. Pour obtenir les valeurs valides des flags, vous devrez importer le tag de groupe d'importation ":sys_wait.h" depuis le module POSIX. Voici un exemple qui réalise une attente non bloquante des processus zombies :

 
Sélectionnez
use POSIX ":queue";
do {
    $fils = waitpid(-1, &WNOHANG);
} until $fils == -1;

Sur les systèmes qui n'implémentent pas les appels système waitpid(2) et wait4(2), les FLAGS ne peuvent être spécifiés qu'à 0. En d'autres termes, vous pouvez attendre là un PID spécifique, mais vous ne pouvez le faire en mode non bloquant.

Sur certains systèmes, une valeur de retour de -1 peut signifier que les processus fils sont automatiquement enterrés, car vous avez fait $SIG{CHLD} = 'IGNORE'.

wantarray

 
Sélectionnez
wantarray

Cette fonction renvoie vrai si le contexte du sous-programme actuellement en train de s'exécuter demande une valeur tableau et faux sinon. La fonction renvoie une valeur définie fausse ("") si le contexte appelant demande un scalaire et la valeur indéfinie fausse (undef) si le contexte appelant ne demande rien de particulier, c'est-à-dire s'il s'agit d'un contexte vide.

Voici quelques exemples d'usages typiques :

 
Sélectionnez
return unless defined wantarray;    # ne se préoccupe pas d'en faire plus
my @a = calcul_complique();
return wantarray ? @a : \@a;

Voir également caller. Cette fonction aurait vraiment dû s'appeler « wantlist », mais nous l'avons baptisée alors que les contextes de listes s'appelaient encore contextes de tableaux.

warn Image non disponible

 
Sélectionnez
warn LISTE
warn

Cette fonction produit un message d'erreur en affichant LISTE sur STDERR exactement comme die, mais sans essayer de sortir ou de lancer une exception. Par exemple :

 
Sélectionnez
warn "Débogage actif" if $debug;

Si LISTE est vide et que $@ contient déjà une valeur (généralement issue d'un eval précédent), la chaîne "\t...caught" est ajoutée à la fin de $@ sur STDERR. (De manière similaire à celle dont die propage les erreurs, excepté le fait que warn ne propage (lève à nouveau) pas l'exception.) Si la chaîne de message fournie est vide, le message « Warning: Something's wrong »(221) est utilisé.

Si la chaîne de message fournie ne se termine pas par un saut de ligne, les informations concernant le fichier et le numéro de ligne sont automatiquement ajoutées à la fin. La fonction warn n'a aucun rapport avec l'option de la ligne de commande de Perl -w, mais elle peut être utilisée en conjonction avec cette dernière, comme lorsque vous voulez émuler le comportement interne :

 
Sélectionnez
warn "Quelque chose de foncièrement mauvais\n" if $^W;

Aucun message n'est affiché si un gestionnaire pour $SIG{__WARN__} est installé. Il appartient au gestionnaire d'en décider si le message lui semble approprié. Une chose que vous pourriez vouloir faire est de promouvoir un simple avertissement en exception :

 
Sélectionnez
local $SIG{__WARN__} = sub {
    my $msg = shift;
    die $msg if $msg =~ /n'est pas numérique/;
}

La plupart des gestionnaires doivent donc faire prendre leurs dispositions pour afficher les avertissements qu'ils n'ont pas prévu de gérer, en appelant à nouveau warn dans le gestionnaire. Ceci est tout à fait sûr ; il n'y aura pas de boucles sans fin, car les routines __WARN__ ne sont pas appelées depuis des routines __WARN__. Ce comportement diffère un peu de celui des gestionnaires de $SIG{__DIE__} (qui ne suppriment pas le texte d'erreur, mais qui peuvent à la place appeler une nouvelle fois die pour le changer).

L'emploi d'un gestionnaire __WARN__ donne un moyen particulièrement puissant de taire tous les avertissements, même ceux qui sont pourtant qualifiés d'obligatoires. Parfois, vos aurez besoin d'encapsuler cela dans un bloc BEGIN{} pour que ce soit pris en compte dès la compilation :

 
Sélectionnez
# nettoie *tous* les avertissements à la compilation
BEGIN { $SIG{__WARN__} = sub { warn $_[0] if $AVERTISSEMENTS_ACTIFS } }
my $truc = 10;
my $truc = 20;              # pas d'avertissement à propos des my $truc
                            # dupliqués, mais, bon, vous l'avez voulu !

# pas d'avertissements à la compilation ou à l'exécution jusqu'ici;
$AVERTISSEMENTS_ACTIFS = 1; # avertissements à l'exécution activés
                            #à partir d'ici
warn "\$truc est vivant et vaut $truc !"; # dénonce tout

Voir le pragma use warnings pour le contrôle de la portée lexicale des avertissements. Voir les fonctions carp et cluck du module Carp pour d'autres moyens de produire des messages d'avertissement.

write Image non disponible Image non disponible Image non disponible

 
Sélectionnez
write HANDLE_FICHIER
write

Cette fonction écrit un enregistrement formaté (qui peut être multiligne) vers le handle de fichier spécifié, en utilisant le format associé à ce handle de fichier — voir la section Variables de format au chapitre 7. Par défaut, le format d'un fichier est celui qui a le même nom que le handle de fichier. Toutefois, le format d'un handle de fichier peut être modifié en changeant la variable $~ après avoir fait un select sur ce handle :

 
Sélectionnez
$ancien_hf = select(HANDLE);
$~ = "NOUVEAU_NOM";
select($ancien_hf);

ou en écrivant :

 
Sélectionnez
use IO::Handle;
HANDLE->format_name("NOUVEAU_NOM");

Puisque les formats sont mis dans l'espace de nom d'un paquetage, il se peut que vous deviez qualifier le nom du format si le format a été déclaré dans un paquetage différent :

 
Sélectionnez
$~ = "Autre_Paquetage::NOUVEAU_NOM";

Le traitement de l'en-tête de formulaire est automatiquement géré : s'il n'y a plus assez de place sur la page courante pour l'enregistrement formaté, la page est avancée en écrivant un saut de page, un format de haut de page spécial est utilisé pour formater le nouvel en-tête de page, et l'enregistrement est enfin écrit. Le nombre de lignes restant sur la page courante se trouve dans la variable $-, qui peut être mise à 0 pour forcer qu'une nouvelle page soit prise au prochain write. (Vous devrez peut-être selectionner d'abord le handle de fichier.) Par défaut, le nom du format de haut de page est celui du handle de fichier auquel est ajouté « _TOP », mais il peut être modifié en changeant la variable $^ après avoir fait un select sur ce handle ou en écrivant :

 
Sélectionnez
use IO::Handle;
HANDLE->format_top_name("NOUVEAU_NOM_TOP");

Si HANDLE_FICHIER n'est pas spécifié, ce qui est écrit sort sur le handle de fichier de sortie par défaut, qui est STDOUT au départ, mais peut être changé par la forme à un seul argument de l'opérateur select. Si HANDLE_FICHIER est une expression, celle-ci est évaluée pour déterminer le véritable HANDLE_FICHIER à l'exécution.

Si un format spécifié ou le format de l'en-tête de page courant n'existe pas, une exception est levée.

La fonction write n'est pas l'inverse de read. Utilisez print pour une simple écriture de chaîne. Si vous avez consulté cette entrée parce que vous voulez court-circuiter les entrées/sorties standard, regardez syswrite.

y/// Image non disponible

 
Sélectionnez
y///

Il s'agit de l'opérateur de traduction (appelé aussi translation), également connu sous le nom de tr///. Voir le chapitre 5.

30. La bibliothèque standard Perl

La distribution standard de Perl contient bien plus que l'exécutable perl qui exécute vos scripts. Elle inclut également des centaines de modules remplis de code réutilisable. Comme les modules standards sont disponibles partout, si vous utilisez l'un d'entre eux dans votre programme, vous pouvez faire tourner votre programme partout où Perl est installé, sans étapes d'installation supplémentaires.

30-1. Bibliothèquologie

Avant d'énumérer ces modules dans les prochains chapitres, passons quelque peu en revue la terminologie dans laquelle nous nageons jusqu'au cou.

espace de noms

  • Les noms sont conservés dans un espace de noms afin de ne pas les confondre avec des noms identiques dans des espaces différents. Ainsi reste à ne pas confondre les espaces de noms entre eux. Il existe deux manières d'éviter cela : leur donner des noms uniques ou leur attribuer des emplacements uniques. Perl vous laisse faire les deux : les espaces de noms nommés s'appellent des paquetages et les espaces de noms anonymes sont appelés portées lexicales. Puisque les portées lexicales ne peuvent pas s'étendre au-delà d'un fichier et puisque les modules standards sont (au minimum) de la taille d'un fichier, il s'ensuit que toutes les interfaces de modules doivent employer des espaces de noms nommés (des paquetages) si quelqu'un doit les utiliser depuis l'extérieur du fichier.

paquetage

  • Un paquetage est un mécanisme standard de Perl pour déclarer un espace de noms nommé. Il s'agit d'un mécanisme très simple pour rassembler des fonctions et des variables qui ont des points communs. Tout comme deux répertoires peuvent contenir tous deux un fichier (différent) s'appelant fred, deux parties d'un programme Perl peuvent, chacune de leur côté, avoir leur propre variable $fred ou leur propre fonction &fred. Même si ces variables ou ces fonctions semblent avoir le même nom, ces noms résident dans des espaces de noms distincts gérés par la déclaration package. Les noms de paquetages sont utilisés pour identifier à la fois des modules et des classes, comme nous l'avons décrit au chapitre 11, Modules et au chapitre 12, Objets.

bibliothèque

  • Le terme bibliothèque (library) est malheureusement suremployé dans la culture Perl. De nos jours, nous utilisons normalement le terme pour désigner l'ensemble des modules Perl installés sur votre système.
  • Historiquement, une bibliothèque Perl était également un simple fichier contenant une collection de sous-programmes partageant un objectif commun. Un tel fichier est souvent suffixé par .pl, pour « perl library ». Nous employons toujours cette extension pour des morceaux variés de code Perl que vous incorporez avec do FICHIER ou require. Bien qu'il ne s'agisse pas d'un module à part entière, un fichier de bibliothèque se déclare généralement lui-même comme étant dans un paquetage distinct, ainsi les variables et les sous-programmes qu'il contient peuvent être rassemblés et n'interfèrent pas accidentellement avec d'autres variables dans votre programme. Il n'y a pas d'extension de fichier obligatoire ; en outre, on rencontre souvent d'autres .pl comme nous le verrons plus loin dans ce chapitre. Ces fichiers de bibliothèques simples et sans structure ont été largement supplantés par les modules.

module

  • Un module Perl est un fichier de bibliothèque conforme à certaines conventions spécifiques qui autorisent un ou plusieurs fichiers implémentant ce module à être rentrés avec une seule déclaration use à la compilation. Les noms de fichier des modules doivent toujours se terminer par .pm, car la déclaration use le présuppose. La déclaration use convertira également le séparateur de paquetage :: vers votre séparateur de répertoire quel qu'il soit afin que la structure des répertoires dans votre bibliothèque Perl puisse refléter la structure de votre paquetage. Le chapitre 11 décrit comment créer vos propres modules Perl.

classe

  • Une classe est juste un module qui implémente des méthodes pour les objets associés au nom du paquetage du module. Si les modules orientés objet vous intéressent, voyez le chapitre 12.

pragma

  • Un pragma est juste un module spécial qui fait joujou avec les boutons internes de Perl. Voir le chapitre 31, Modules de pragmas.

extension

  • Une extension est un module Perl qui, en plus de charger un fichier .pm, charge également une bibliothèque partagée implémentant en C ou en C++ la sémantique du module.

programme

  • Un programme Perl est un code conçu pour tourner en tant qu'entité indépendante ; il est également connu sous le nom de script lorsque vous ne voulez pas que quiconque en attende un peu trop, sous le nom d'application lorsqu'il est volumineux et compliqué, sous le nom d'exécutable lorsque celui qui l'appelle ne se soucie pas du langage dans lequel il a été écrit, ou encore sous le nom de solution industrielle lorsqu'il coûte une fortune. Les programmes Perl existent en tant que code source, bytecode ou code machine natif. S'il s'agit de quelque chose que vous pouvez lancer depuis la ligne de commande, nous l'appellerons un programme.

30-2. Visite guidée de la bibliothèque Perl

Vous gagnerez énormément de temps si vous faites l'effort de vous familiariser avec la bibliothèque Perl standard, car il n'y a aucune raison de réinventer la roue. Nous devons toutefois vous avertir que cette collection contient un vaste champ de matières premières. Bien que certaines bibliothèques soient extrêmement utiles, d'autres peuvent être sans aucun rapport avec vos besoins. Par exemple, si vous n'écrivez que du code Perl pur à 100 %, les modules qui supportent le chargement dynamique d'extensions C et C++ ne vont pas beaucoup vous aider.

Perl s'attend à trouver les modules de bibliothèque quelque part dans son chemin d'inclusion (N.d.T. :« include ») de bibliothèque, @INC. Ce tableau spécifie la liste ordonnée des répertoires où Perl cherche lorsque vous chargez du code de bibliothèque en utilisant les mots clefs do, require ou use. Vous pouvez facilement afficher la liste de ces répertoires en appelant Perl avec l'option -V, pour Version Vraiment Verbeuse, ou avec ce simple code :

 
Sélectionnez
% perl -le "print foreach @INC"
/usr/libdata/perl5/sparc-openbsd/5.00503
/usr/local/libdata/perl5/sparc-openbsd/5.00503
/usr/libdata/perl5
/usr/local/libdata/perl5
/usr/local/libdata/perl5/site_perl/sparc-openbsd
/usr/libdata/perl5/site_perl/sparc-openbsd
/usr/local/libdata/perl5/site_perl
/usr/libdata/perl5/site_perl
.

Il ne s'agit que d'un exemple d'affichage possible. Chaque installation de Perl utilise ses propres chemins. Le point important est que, malgré la variation des contenus selon la politique de votre constructeur et de celle de l'installation sur votre site, vous pouvez compter sur toutes les bibliothèques standards qui sont installées avec Perl. Si vous voulez retrouver l'endroit depuis lequel un fichier a été réellement chargé, consultez la variable %INC. Pour un fichier de module, vous pouvez trouver exactement où Perl l'a trouvé avec cette commande :

 
Sélectionnez
% perldoc -l MODULE

Si vous regardez les répertoires de @INC et leurs sous-répertoires, vous trouverez différentes sortes de fichiers installés. La plupart ont des noms se terminant par .pm, mais certains se finissent par .pl, .ph, .al ou .so. Ceux qui vous intéressent le plus sont dans la première catégorie, car un suffixe .pm indique que le fichier est un module Perl authentique. Nous en dirons plus sur ceux-là dans un instant.

Le peu de fichiers que vous verrez là finissant par .pl sont ces vieilles bibliothèques Perl que nous avons mentionnées plus haut. Ils sont inclus pour garder une compatibilité avec d'anciennes versions de Perl datant des années 80 et du début des années 90. Ainsi, le code Perl qui marchait, disons en 1990, doit continuer à bien se comporter sans histoires même si vous avez installé une version moderne de Perl. Lorsque vous êtes en train d'écrire du code nouveau, vous devez toujours préférer, lorsque c'est possible, utiliser la version avec .pm plutôt que celle avec .pl. Ainsi, les modules ne pollueront pas votre espace de noms comme beaucoup des vieux fichiers .pl le font.

Une remarque à propos de l'emploi de l'extension .pl : elle signifie Perl library (bibliothèque Perl), et non pas programme Perl. Bien que l'extension .pl soit utilisée pour identifier les programmes Perl sur les serveurs web qui ont besoin de distinguer, dans le même répertoire, les programmes exécutables des contenus statiques, nous vous suggérons d'employer un suffixe de .plx à la place pour indiquer un programme Perl exécutable. (Le même conseil vaut pour les systèmes d'exploitation qui choisissent les interpréteurs en se basant sur les extensions des noms de fichiers.)

Les fichiers avec des extensions .al sont de petits morceaux de modules plus grands qui sont automatiquement chargés lorsque vous utiliser leur fichier parent .pm. Si vous construisez le plan de votre module en utilisant l'outil standard h2xs qui est fourni avec Perl (et si vous n'avez pas employé le flag Perl -A), la procédure make install utilisera le module Autoloader pour créer pour vous ces petits fichiers .al.

Les fichiers .ph sont construits par le programme h2ph, un outil quelque peu vieillissant, mais parfois toujours utile pour convertir des directives de préprocesseur C vers du Perl. Les fichiers .ph résultants contiennent des constantes parfois nécessaires aux fonctions de bas niveau comme ioctl, fnctl ou syscall. (De nos jours la plupart de ces valeurs sont disponibles, plus facilement et de manière plus portable, dans des modules standards comme POSIX, Errno, Fcntl ou Sockets.) Voir perlinstall pour savoir comment installer ces composants optionnels, mais parfois importants.

La dernière extension que vous pourriez rencontrer en errant ici et là est .so (ou ce que votre système emploie pour les bibliothèques partagées). Ces fichiers .so sont des portions de modules d'extension qui sont dépendantes de la plate-forme. Elles sont écrites en C ou en C++ et il faut les compiler pour obtenir le code objet relogeable dynamiquement. L'utilisateur final n'a de toute façon pas besoin d'être au courant de leur existence, car elles sont masquées par l'interface du module. Lorsque le code de l'utilisateur dit require Module ou use Module, Perl charge Module.pm et l'exécute, ce qui laisse le module attirer à lui toute autre partie nécessaire, comme Module.so ou tous les composants .al autochargés. En fait, le module peut charger tout ce qui lui plaît, y compris 582 autres modules. Il peut télécharger l'intégralité de CPAN s'il le veut et pourquoi pas les archives des deux dernières années de freshmeat.net.

Un module n'est pas simplement un morceau de code statique en Perl. C'est un agent actif qui arrive à comprendre comment implémenter pour vous une interface. Il peut suivre toutes les conventions standards, ou pas. Il lui est permis de tout faire pour pervertir la signification du reste de votre programme, y compris jusqu'à convertir le reste de votre programme en SPITBOL. Ce genre de canular est considéré comme étant parfaitement loyal pour autant qu'il soit bien documenté. Lorsque vous utilisez un tel module Perl, vous acceptez son contrat, non un contrat standard écrit par Perl.

Vous feriez donc mieux de lire les petits caractères de la notice.

31. Modules de pragmas

Un pragma est un type particulier de module qui affecte la phase de compilation de votre programme. Certains modules de pragmas (ou pragmata, pour faire court, ou pragmas, pour faire encore plus court) peuvent également affecter la phase d'exécution de votre programme. Voyez-les comme des indications données au compilateur. Comme ils ont besoin d'être visibles à la compilation, ils ne fonctionnent que lorsqu'ils sont invoqués par un use ou un no, car lorsqu'un require ou un do s'exécute, la compilation est finie depuis longtemps.

Par convention, les noms de pragmas sont écrits en minuscules, car les noms de modules en minuscules sont réservés pour la distribution Perl elle-même. Lorsque vous écrivez vos propres modules, utilisez au moins une lettre majuscule pour éviter d'entrer en conflit avec les noms de pragmas.

Au contraire des modules ordinaires, la plupart des pragmas limitent leurs effets au reste du bloc le plus interne encadrant l'endroit d'où ils ont été appelés. En d'autres termes, ils sont limités à une portée lexicale, exactement comme les variables my. Habituellement, la portée lexicale d'un bloc extérieur couvre tout bloc intérieur inclus dans le premier, mais un bloc intérieur peut contredire un pragma de portée lexicale provenant d'un bloc extérieur avec l'instruction no :

 
Sélectionnez
use strict;
use integer;
{
    no strict 'refs';   # permet les références symboliques
    no integer;         # reprend l'arithmétique en virgule flottante
    # ...
}

Plus encore que les autres modules inclus dans la distribution Perl, les pragmas forment une partie intégrale et essentielle de l'environnement de compilation en Perl. Il est difficile de bien utiliser le compilateur si vous ne savez pas comment lui passer des indications, nous produirons donc un effort supplémentaire à décrire les pragmas.

Un autre point auquel il faut prêter attention est le fait que nous utilisons souvent les pragmas pour prototyper des fonctionnalités qui seront plus tard encodées dans une syntaxe « réelle ». Ainsi vous verrez dans quelques programmes des pragmas dépréciés comme use attrs dont la fonctionnalité est maintenant directement supportée par la syntaxe de déclaration des sous-programmes. De même, use vars est en cours de remplacement par les déclarations our. Et use subs peut un jour être remplacé par un attribut override dans les déclarations de sous-programmes ordinaires. Nous ne sommes pas extrêmement pressés de casser les anciennes pratiques, mais nous pensons assurément que les nouvelles pratiques sont plus jolies.

31-1. use attributes

 
Sélectionnez
sub une_fonct : method;
my $fermeture = sub : method { };

use attributes;
@liste_attrs = attributes::get(\&une_fonct);

Le pragma attributes a deux objectifs. Le premier est de fournir un mécanisme interne pour déclarer des listes d'attributs, qui sont des propriétés optionnelles associées aux déclarations de sous-programmes et (dans un futur proche) aux déclarations de variables. (Puisqu'il s'agit d'un mécanisme interne, vous ne devriez pas en général utiliser ce pragma directement.) Le second objectif est de fournir un moyen de récupérer ces listes d'attributs à l'exécution en appelant la fonction attribute::get. Dans cette fonctionnalité, attributes est juste un module standard et non un pragma.

Perl ne gère actuellement qu'un petit nombre d'attributs en interne. Les attributs spécifiques à un paquetage sont autorisés par le biais d'un mécanisme d'extension expérimental décrit dans la section Package-specific Attribute Handling (N.d.T. : gestion d'attributs spécifiques à un paquetage) de la page de man attributes(3).

Le positionnement des attributs intervient à la compilation ; la tentative de positionner un attribut inconnu provoque une erreur de compilation. (L'erreur peut être interceptée avec eval, mais elle continuera d'arrêter la compilation à l'intérieur du bloc eval.)

Il n'existe actuellement que trois attributs internes implémentés pour les sous-programmes : locked, method et lvalue. Voir le chapitre 6, Sous-programmes et le chapitre 7, Threads, pour une discussion approfondie sur ces attributs. Il n'existe pas actuellement d'attributs internes pour les variables comme il y en a pour les sous-programmes, mais nous en avons plusieurs en tête que nous aimons bien, comme constant.

Le pragma attributes fournit deux sous-programmes pour un usage générique. Ils peuvent être importés si vous les demandez :

get

  • Cette fonction renvoie une liste (qui peut être vide) des attributs lorsqu'on lui donne un seul paramètre en entrée, lequel est une référence à un sous-programme ou à une variable. La fonction lève une exception en invoquant Carp::croak si on lui passe des arguments invalides.

reftype

  • Cette fonction se comporte plus ou moins comme la fonction interne, ref mais elle renvoie toujours le type de donnée sous-jacent intrinsèque à Perl ou la valeur référencée, en ignorant tout paquetage dans lequel elle pourrait avoir été consacrée.

Des détails plus précis sur la gestion des attributs sont toujours en cours de discussion, vous feriez donc mieux de consulter la documentation en ligne de votre distribution de Perl pour savoir quel est l'état en cours.

31-2. use autouse

 
Sélectionnez
use autouse 'Carp' => qw(carp croak);
carp "Cet appel à carp a été prédéclaré avec autouse\n";

Ce pragma fournit un mécanisme pour une demande de chargement à l'exécution d'un module particulier si et seulement si une fonction de ce module est réellement appelée. Il accomplit ceci en donnant une souche (stub) de fonction qui est remplacée par l'appel réel lorsqu'on la déclenche. Dans l'esprit, ce mécanisme est similaire au comportement des modules standards AutoLoader et SelfLoader. Pour faire court, c'est une astuce de performance qui facilite le démarrage plus rapide (en moyenne) de votre programme Perl en évitant la compilation de modules qui pourraient ne jamais être appelés durant une exécution donnée du programme.

Le comportement de autouse est lié au fait que le module soit déjà chargé ou non. Par exemple, si le module Module est déjà chargé, alors la déclaration :

 
Sélectionnez
use autouse 'Module' => qw(fonc1 fonc2($;$) Module::fonc3);

est équivalente à la simple importation de deux fonctions :

 
Sélectionnez
use Module qw(fonc1 fonc2);

Cela suppose que Module définisse fonc2 avec le prototype ($;$) et que fonc1() et fonc3() n'aient pas de prototype. (Plus généralement, cela suppose également que Module utilise la méthode import du module standard Exporter; sinon, une exception est levée.) Dans tous les cas, la déclaration Module::fonc3 est ignorée puisqu'elle est certainement déjà déclarée.

Si, d'un autre côté, Module n'a pas encore été chargé lorsque le pragma autouse est analysé, ce dernier déclare les fonctions fonc1 et fonc2 dans le paquetage courant. Il déclare également une fonction Module::fonc3 (ce que l'on pourrait analyser comme étant légèrement antisocial, si ce n'est que l'absence du module Module aurait des conséquences encore plus antisociales). Lorsque ces fonctions sont appelées, elles s'assurent que le Module en question est chargé et elles sont alors remplacées par les appels aux fonctions réelles qui viennent d'être chargées.

Puisque le pragma autouse déplace des portions de votre programme depuis la compilation vers l'exécution, cela peut avoir des ramifications déplaisantes. Par exemple, si le module sur lequel vous avez appliqué autouse possède une phase d'initialisation qui s'attend à être passée au plus tôt, celle-ci pourra ne pas arriver assez tôt. L'emploi de autouse peut également masquer des bogues dans votre code lorsque d'importantes vérifications sont déplacées de la compilation vers l'exécution.

En particulier, si le prototype que vous avez spécifié dans la ligne autouse est faux, vous ne le découvrirez pas avant que la fonction correspondante soit exécutée (ce qui peut se produire des mois ou des années plus tard, pour une fonction rarement appelée). Pour résoudre partiellement ce problème, vous pouvez écrire votre code ainsi durant votre phase de développement :

 
Sélectionnez
use Chasse;
use autouse Chasse => qw(tolle($) clameur($&));
clameur "Cette clameur a été prédéclarée avec autouse\n";

La première ligne s'assure que les erreurs dans votre spécification des arguments soient trouvées assez tôt. Lorsque votre programme passe de la phase de développement à la phase de production, vous pouvez mettre en commentaire le chargement ordinaire du module Chasse et laisser seulement l'appel à autouse. De cette manière, vous obtenez de la sécurité pendant le développement et des performances durant la production.

31-3. use base

 
Sélectionnez
use base qw(Mere Pere);

Ce pragma permet à un programmeur de déclarer aisément une classe dérivée basée sur les classes parentes listées. La déclaration ci-dessus est à peu près équivalente à :

 
Sélectionnez
BEGIN {
    require Mere;
    require Pere;
    push @ISA, qw(Mere Pere)
}

Le pragma use base s'occupe de chaque require nécessaire. Lorsque vous êtes dans la portée du pragma strict 'vars', use base vous laisse faire (effectivement) un assigne-ment de @ISA sans avoir à déclarer d'abord our @ISA. (Puisque le pragma use base intervient lors de la compilation, il vaut mieux éviter de titiller @ISA dans votre coin lors de l'exécution.)

Mais au-delà de ceci, use base possède une autre propriété. Si l'une des classes de base nommées utilise les facilités de use fields décrites plus loin dans ce chapitre, alors le pragma initialise les attributs spéciaux de champs du paquetage depuis la classe de base. (L'héritage multiple des classes de champs n'est pas supporté. Le pragma use base lève une exception si plus d'une des classes de base nommées possède des champs.)

Toute classe de base qui n'a pas encore été chargée l'est automatiquement via require. Toutefois, le fait que l'on doive ou non charger un paquetage d'une classe de base avec require est déterminé, non pas par l'inspection habituelle de %INC, mais par l'absence d'une variable globale $VERSION dans le paquetage de base. Cette astuce évite à Perl d'essayer en boucle (et d'échouer) de charger une classe de base qui ne se trouve pas dans le fichier que l'on appelle par require (car, par exemple, elle est chargée en tant que faisant partie du fichier d'un autre module). Si $VERSION n'est pas détectée après avoir réussi à charger le fichier, use base définira $VERSION dans le paquetage de base, en la positionnant à la chaîne « -1, defined by base.pm».

31-4. use blib

Depuis la ligne de commande :

 
Sélectionnez
% perl -Mblib programme [args...]
% perl -Mblib=REP programme [args...]

Depuis votre programme Perl :

 
Sélectionnez
use blib;
use blib 'REP ';

Ce pragma est en premier lieu un moyen de tester arbitrairement les programmes Perl pour découvrir une version non installée d'un paquetage grâce à l'option de la ligne de commande de Perl -M. Il suppose que la structure de vos répertoires a été produite par le module standard ExtUtils::MakeMaker.

Le pragma cherche une structure de répertoire blib commençant depuis un répertoire nommé REP (ou le répertoire courant si l'on n'en a spécifié aucun) et s'il n'y trouve pas de répertoire blib, il revient en arrière à travers vos répertoires « .. », en remontant jusqu'au cinquième niveau dans les répertoires parents.

31-5. use bytes

 
Sélectionnez
use bytes;
no bytes;

Le pragma use bytes désactive la sémantique des caractères pour le reste de la portée lexicale dans lequel il apparaît. Le pragma no bytes peut être employé pour inverser les effets de use bytes à l'intérieur de la portée lexicale courante.

Perl présume normalement une sémantique de caractères en présence d'une donnée sous forme de caractères (c'est-à-dire, une donnée notée comme étant dans un encodage de caractère particulier).

Pour comprendre les implications et les différences entre les sémantiques de caractères et les sémantiques d'octets, voir le chapitre 15, Unicode. Une visite à Tokyo peut également être utile.

31-6. use charnames

 
Sélectionnez
use charnames COMMENT;
print "\N{SPEC_CAR} est un drôle de caractère";

Ce pragma de portée lexicale permet aux caractères nommés d'être interpolés vers des chaînes en utilisant la notation \N{SPEC_CAR} :

 
Sélectionnez
use charnames ':full';
print "\N{GREEK SMALL LETTER SIGMA} est appelée sigma.\n";

use charnames ':short';
print "\N{greek:Sigma} est appelée sigma.\n";

use charnames qw(cyrillic greek); print "\N{sigma} est sigma en grec et \N{be} est b en cyrillique.\n";

Le pragma supporte les valeurs :full et :short pour le paramètre COMMENT, ainsi que des noms de scripts spécifiques.(222) L'argument COMMENT détermine comment rechercher le caractère spécifié par SPEC_CAR dans \N{SPEC_CAR}. Si :full est présent, SPEC_CAR est d'abord cherché dans les tables de caractères Unicode en tant que nom complet de caractère Unicode. Si :short est présent et que SPEC_CAR est de la forme NOM_SCRIPT:NOM_CAR, NOM_CAR est recherché en tant que lettre dans le script NOM_SCRIPT. Si COMMENT contient des noms de scripts spécifiques, SPEC_CAR est recherché en tant que NOM_CAR dans chacun des scripts donnés et dans l'ordre spécifié.

Pour la recherche de NOM_CAR dans un script NOM_SCRIPT donné, le pragma regarde dans la table des noms standards Unicode s'il peut trouver des motifs ayant la forme de :

 
Sélectionnez
NOM_SCRIPT CAPITAL LETTER NOM_CAR
NOM_SCRIPT SMALL LETTER NOM_CAR
NOM_SCRIPT LETTER NOM_CAR

Si NOM_CAR est entièrement en minuscules (comme dans \N{sigma}), la variante CAPITAL est ignorée.

Vous pouvez écrire votre propre module fonctionnant comme le pragma, charnames mais définissant différemment les noms de caractères. Toutefois, l'interface pour cela est toujours expérimentale, consultez donc son état courant dans la page de man.

31-7. use constant

 
Sélectionnez
use constant TAILLE_TAMPON      => 4096;
use constant UNE_ANNEE          => 365.2425 * 24 * 60 * 60;
use constant PI                 => 4 * atan2 1, 1;
use constant DEBOGAGE           => 0;
use constant ORACLE             => 'oracle@cs.indiana.edu';
use constant NOM_UTILISATEUR    => scalar getpwuid($<);
use constant INFOS_UTILISATEUR  => getpwuid($<);

sub deg_rad { PI * $_[0] / 180 }

print "Cette ligne ne fait rien" unless DEBOGAGE;
# Les références peuvent être déclarées en tant que constantes
use constant C_HACHAGE          => { truc => 42 };
use constant C_TABLEAU          => [ 1,2,3,4 ];
use constant C_PSEUDO_HACH      => [ { truc => 1 }, 42];
use constant C_CODE             => sub { "mord $_[0]\n" };

print C_HACHAGE->{truc};
print C_TABLEAU->{$i];
print C_PSEUDO_HACH->{truc};
print C_CODE->{"moi"};
print C_HACHAGE->[10];      # erreur à la compilation

Ce pragma déclare le symbole nommé comme étant une constante immuable(223) avec la valeur scalaire ou de liste donnée. Vous devez faire une déclaration séparée pour chaque symbole. Les valeurs sont évaluées dans un contexte de liste. Vous pouvez outrepasser cela avec scalar comme nous l'avons fait ci-dessus.

Puisque les constantes ne commencent pas par un $, vous ne pouvez pas les interpoler directement dans les chaînes entre guillemets, bien que ce soit possible indirectement :

 
Sélectionnez
print "La valeur de PI est @{[ PI ]}.\n";

Comme les constantes de liste sont renvoyées en tant que listes, et non en tant que tableaux, vous devez indicer une constante représentant une valeur de liste en utilisant des parenthèses supplémentaires comme vous le feriez avec toute autre expression de liste :

 
Sélectionnez
$rep_maison = INFO_UTILISATEUR[7];    # FAUX
$rep_maison = (INFO_UTILISATEUR)[7];  # OK

Bien que l'on recommande d'écrire les constantes entièrement en majuscules pour les faire ressortir et pour aider à éviter les collisions potentielles avec d'autres mots-clefs et noms de sous-programmes, il ne s'agit que d'une convention. Les noms de constantes doivent commencer par une lettre, mais celle-ci n'a pas besoin d'être en majuscule.

Les constantes ne sont pas privées dans la portée lexicale dans laquelle elles apparaissent. Elles sont plutôt de simples sous-programmes sans argument dans la table de symboles du paquetage où a lieu la déclaration. Vous pouvez vous référer à une constante CONST depuis un paquetage Autre en écrivant Autre::CONST. Approfondissez la notion d'insertion en ligne (N.d.T. : inlining) de tels sous-programmes à la compilation en lisant la section Substitution en ligne de fonctions constantes au chapitre 6.

Comme dans toutes les directives use, use constant intervient à la compilation. Ainsi, placer une déclaration de constante à l'intérieur d'une instruction conditionnelle comme if ($truc) { use constant ... } est une incompréhension totale.

Si l'on omet la valeur pour un symbole, ce dernier prendra la valeur undef dans un contexte scalaire ou la liste vide dans un contexte de liste. Mais il vaut probablement mieux déclarer ceux-ci explicitement :

 
Sélectionnez
use constant CAMELIDE       => ();
use constant MAISON_CHAMEAU => undef;
31-7-a. Restrictions de use constant

Les listes constantes ne sont pas actuellement insérées en ligne de la même manière que les scalaires. Et il n'est pas possible d'avoir un sous-programme ou un mot clef du même nom qu'une constante. C'est probablement une Bonne Chose.

Vous ne pouvez pas déclarer plus d'une constante nommée à la fois :

 
Sélectionnez
use constant TRUC => 4, MACHIN => 5; # FAUX

Ceci définit une constante nommée TRUC qui renvoie une liste (4, "MACHIN", 5). Vous devez plutôt écrire :

 
Sélectionnez
use constant TRUC   => 4;
use constant MACHIN => 5;

Vous allez au-devant des problèmes si vous utilisez une constante dans un contexte qui met automatiquement les mots bruts entre guillemets. (Ceci est vrai pour tout appel de sous-programme, pas seulement pour les constantes.) Par exemple vous ne pouvez pas écrire, $hachage{CONSTANTE} car CONSTANTE serait interprétée comme une chaîne. Utilisez $hachage{CONSTANTE()} ou $hachage{+CONSTANTE} pour empêcher le mécanisme de mise entre guillemets de se mettre en branle. De même, puisque l'opérateur => met entre guillemets son opérande de gauche si cette dernière est un nom brut, vous devez écrire CONSTANTE() => 'valeur' au lieu de CONSTANTE => 'valeur'.

Un jour, vous serez capables d'utiliser un attribut constant dans les déclarations de variables :

 
Sélectionnez
my $PI : constant = 4 * atan2(1,1);

Ceci possède tous les avantages d'être une variable plutôt qu'un sous-programme, mais tous les inconvénients de ne pas être encore implémenté.

31-8. use diagnostics

 
Sélectionnez
use diagnostics;            # activé à la compilation
use diagnostics -verbose;

enable diagnostics;         # activé à l'exécution
disable diagnostics;        # désactivé à l'exécution

Ce pragma étend les diagnostics ordinaires, laconiques et supprime les avertissements dupliqués. Il augmente les versions abrégées avec les descriptions plus explicites et plus agréables que l'on peut trouver au chapitre 33, Messages de diagnostic. Comme les autres pragmas, celui-ci affecte également la phase de compilation de votre programme, pas seulement la phase d'exécution.

Lorsque vous utilisez use diagnostics au début de votre programme, l'option Perl -w de la ligne de commande est automatiquement activée en mettant $^W à 1. La suite de votre entière compilation sera alors sujette à des diagnostics améliorés. Ces derniers sont toujours envoyés vers STDERR.

En raison des interactions entre les résultats d'exécution et de compilation, et parce que ce n'est souvent pas une très bonne idée, vous ne devriez pas utiliser no diagnostics pour désactiver les diagnostics à la compilation. Vous pouvez néanmoins contrôler leur comportement à l'exécution en utilisant les méthodes enable et disable, pour respectivement les activer et les désactiver. (Assurez-vous d'avoir d'abord fait le use ou sinon vous serez incapables d'accéder aux méthodes.)

Le flag -verbose affiche d'abord l'introduction de la page man de perldiag avant tout autre diagnostic. La variable $diagnostics::PRETTY peut être positionnée (avant le use) pour générer de meilleures séquences d'échappement pour les pagineurs comme less(1) ou more(1) :

 
Sélectionnez
BEGIN { $diagnostics::PRETTY = 1 }
use diagnostics;

Les avertissements envoyés par Perl et détectés par ce pragma ne sont affichés qu'une seule fois chacun. Ceci est utile lorsque vous êtes pris dans une boucle qui génère encore et toujours le même avertissement (comme une valeur non initialisée). Les avertissements générés manuellement, comme ceux découlant des appels à warn ou carp, ne sont pas affectés par ce mécanisme de détection des duplications.

Voici quelques exemples d'utilisation du pragma diagnostics. Le fichier suivant déclenche à coup sûr quelques erreurs tant à la compilation qu'à l'exécution :

 
Sélectionnez
use diagnostics; 
print NULLE_PART "rien\n"; 
print STDERR "\n\nCe message devrait rester tel quel.\n"; 
warn "\tAvertissement utilisateur"; 
print "\nTESTEUR DE DIAGNOSTIC : Entrez un <RETOUR_CHARIOT> ici : "; 
my $a, $b = scalar <STDIN>; 
print "\n"; 
print $x/$y;

ce qui affiche :

 
Sélectionnez
Parenthesis missing around "my" list at diagtest line 6 (#1)
    (W parenthesis) You said something like
        my $foo, $bar = @_;
    when you meant
        my ($foo, $bar) = @_;

Remember that "my", "our", and "local" bind tighter than comma.

Name "main::NULLE_PART" used only once: possible typo at diagtest line 2 (#2)

(W once) Typographical errors often show up as unique variable
    names. If you had a good reason for having a unique name,
    then just mention it again somehow to suppress the message.
    The our declaration is provided for this purpose.

Name "main::b" used only once: possible typo at diagtest line 6 (#2) Name "main::x" used only once: possible typo at diagtest line 8 (#2) Name "main::y" used only once: possible typo at diagtest line 8 (#2)

Filehandle main::NULLE_PART never opened at diagtest line 2 (#3)

(W unopened) An I/O operation was attempted on a filehandle that
    was never initialized. You need to do an open() or a socket()
    call, or call a constructor from the FileHandle package.

        Ce message devrait rester tel quel.
        Avertissement utilisateur at diagtest line 4.

TESTEUR DE DIAGNOSTIC : Entrez un <RETOUR_CHARIOT> ICI : Use of uninitialized value in division (/) at diagtest line 8 (#4)

(W uninitialized) An undefined value was used as if it were
    already defined. It was interpreted as a "" or a 0, but maybe
    it was a mistake. To suppress this warning assign a defined
    value to your variables.

Illegal division by zero at diagtest line 8 (#5)

(F) You tried to divide a number by 0. Either something was
    wrong in your logic, or you need to put a conditional in to
    guard against meaningless input.

Uncaught exception from user code:
    Illegal division by zero at diagtest line 8.

Les messages de diagnostic sont tirés du fichier perldiag.pod. Si un gestionnaire $SIG{__WARN__} existant est détecté, il sera toujours respecté, mais seulement après que la fonction diagnostics::splainthis (l'intercepteur de $SIG{__WARN__} pour le pragma) aura fait son travail pour vos avertissements. Perl ne supporte pas à l'heure actuelle les empilements de gestionnaires, c'est donc le mieux que nous puissions faire pour l'instant. Il existe une variable $diagnostics::DEBUG que vous pouvez positionner si vous êtes d'incurables curieux à propos des genres de choses qui sont interceptées.

 
Sélectionnez
BEGIN { $diagnostics::DEBUG = 1 } 
use diagnostics;

31-9. use fields

Dans le module Animal :

 
Sélectionnez
package Animal; 
use strict; 
use fields qw(nom poids _Animal_id); 
my $ID = 0; 
sub new {
    my Animal $obj = shift;
    unless (ref $obj) {
        $obj = fields::new($obj);
        $obj->{_Animal_id} = "ceci est l'ID secret de l'Animal";
    }
    $obj->{nom} = "Hé, toi !";
    $obj->{poids} = 20;
    return $obj;
} 
1;

Dans un programme séparé, demo_animal :

 
Sélectionnez
use Animal;
my Animal $rock = new Animal; # lexicalement typé

$rock->{nom} = "quartz";
$rock->{poids} = "2kg";
$rock->{_Animal_id} = 1233;   # attribut privé

$rock->{couleur} = "bleu";    # génère une erreur de compilation

Dans le module Chien :

 
Sélectionnez
package Chien;
use strict;
use base 'Animal';                # hérite les champs et méthodes d'Animal
use fields qw(nom pedigree);      # surcharge l'attribut nom d'Animal
                                  # et ajoute un nouvel attribut pedigree
use fields qw(remue _Chien_prive) # non-partagé avec Animal
sub new {
    my $classe = shift;
    my $obj = fields::new{$classe};
    $obj_>SUPER::new();           # initialise les champs de base
    $obj->{pedigree} = "aucun";   # initialise ses propres champs
    return $obj;
}

Dans un programme séparé, demo_chien :

 
Sélectionnez
use Chien;

my Chien $medor = new Chien     # lexicalement typé
$medor->{nom} = "Theloneus"     # non-hérité
$medor->{poids} = "30lbs";      # hérité
$medor->{pedigree} = "bâtard";  # non-hérité

$medor->{couleur} = 'brun';     # génère une erreur de compilation
$medor->{_Animal_pid} = 3324;   # génère une erreur de compilation

Le pragma fields fournit une méthode pour déclarer les champs de classe dont le type peut être vérifié à la compilation. Ceci repose sur une fonctionnalité connue sous le nom de pseudohachages : si une variable lexicale typée (my Animal $rock) contient une référence (l'objet Animal) et est utilisée pour accéder à un élément de hachage ($rock>{nom}), s'il existe un paquetage du même nom que le type déclaré, et si ce paquetage a positionné des champs de classe en utilisant le pragma fields, alors l'opération se change en accès à un tableau lors de la compilation, pourvu que le champ spécifié soit valide.

Le pragma base apparenté combinera les champs des classes de base et ceux déclarés avec le pragma fields. Ceci rend permet à l'héritage de champ de bien fonctionner.

Les noms de champ qui commencent par un caractère souligné sont rendus privés pour la classe et invisibles dans les sous-classes. Les champs hérités peuvent être surchargés, mais généreront un avertissement si les avertissements sont activés.

La conséquence de tout ceci est que vous pouvez avoir des objets avec des champs nommés qui soient aussi compacts que des tableaux avec un accès aussi rapide. Cependant, ceci ne fonctionne que tant que l'on accède aux objets à travers des variables convenablement typées. Si les variables ne sont pas typées, l'accès est uniquement vérifié à l'exécution, votre programme tourne donc plus lentement, car il doit accéder à la fois à un hachage et à un tableau. En plus des déclarations de champs, les fonctions suivantes sont supportées :

new

  • La fonction fields::new crée et consacre un pseudohachage dans la classe spécifiée (qui peut également être spécifiée en passant un objet de cette classe). L'objet est créé avec les champs déclarés auparavant pour cette classe avec le pragma fields. Ceci autorise l'écriture d'un constructeur comme ceci :
 
Sélectionnez
package Creature::Sons;
use fields qw(chat chien oiseau);

sub new {
    my Creature:Sons $obj = shift;
    $obj = fields::new($obj) unless ref $obj;
    $obj->{chat} = 'miaule';                       # élément scalaire
    @$obj{'chien', 'oiseau'} = ('aboie','siffle'); # tranche
    return $obj;
}

phash

  • La fonction fields::phash crée et initialise un pseudohachage brut (non consacré). Vous devriez toujours utiliser cette fonction pour créer des pseudohachages au lieu de le faire directement, au cas où nous décidions de changer l'implémentation.

Si le premier argument de phash est une référence à un tableau, le pseudohachage sera créé avec des clefs provenant de ce tableau. Si le second argument est fourni, ce doit être également une référence à un tableau dont les éléments seront utilisés comme valeurs. Si le second tableau contient moins d'éléments que le premier, les éléments restants du pseudohachage ne seront pas initialisés. Ceci est particulièrement utile pour créer un pseudohachage à partir des arguments d'un sous-programme :

 
Sélectionnez
sub chien_option {
    my $option = fields::phash([qw(nom grade matricule)], [@_]); 
}

Vous pouvez aussi passer une liste de paires clef/valeur qui sera utilisée pour construire le pseudohachage :

 
Sélectionnez
my $option = fields::phash(nom => "Joe",
                           grade => "capitaine",
                           matricule => 42);

my $pseudo_hachage = fields::phash(%args);

Pour plus d'information sur les pseudohachages, voir la section « Pseudohachages » au chapitre 8, Références.

L'implémentation actuelle conserve les champs déclarés dans le hachage %FIELDS du paquetage appelant, mais cela peut changer dans les prochaines versions, il vaut donc mieux vous fier à l'interface de ce pragma pour gérer vos champs.

31-10. use filetest

 
Sélectionnez
$lecture_peut_etre_possible = -r "fichier"     # utilise les bits de mode
{
    use filetest 'access';
    $lecture_vraiment_possible = -r "fichier"  # dépiste plus sérieusement
}
$lecture_peut_etre_possible = -r "fichier";    # utilise à nouveau les
                                               #bits de mode

Ce pragma de portée lexicale indique au compilateur de changer le comportement des opérateurs unaires de test de fichier -r, -w, -x, -R, -W et -X, documentés au chapitre 3, Opérateurs unaires et binaires. Le comportement par défaut de ces tests de fichiers est d'utiliser les bits de mode renvoyés par les appels de la famille de stat. Toutefois, ce n'est peut-être pas toujours la façon correcte de faire, comme lorsqu'un système de fichiers comprend les ACL (Access Control Lists, listes de contrôle d'accès). Dans les environnements où cela compte, comme AFS, le pragma use filetest peut aider les opérateurs de permissions à renvoyer des résultats plus cohérents avec d'autres outils.

Il peut y avoir une légère baisse de performance pour les opérateurs de test de fichier affectés lorsqu'on les utilise avec use filetest, car sur certains systèmes les fonctionnalités étendues ont besoin d'être émulées.

Attention : toute notion d'utilisation de tests de fichiers dans des objectifs de sécurité est une cause perdue d'avance. La porte est grande ouverte pour des situations de concurrence (race conditions), car il n'y a aucun moyen de garantir que les permissions ne changeront pas entre le test et l'opération effective. Si vous êtes ne serait-ce qu'un peu sérieux avec la sécurité, vous n'utiliserez pas d'opérateurs de test de fichier pour décider si quelque chose va marcher ou pas. À la place, essayez de lancer l'opération réelle puis testez si l'opération a réussi ou non. (Vous devriez de toute façon faire cela.) Voir la section Gestion des problèmes de synchronisation au chapitre 23, Sécurité.

31-10-a. use filetest 'access'

Actuellement une seule importation, access, est implémentée. L'appel de use file-test 'access' active l'emploi d'access(2) ou d'appels systèmes équivalents lorsqu'on lance des tests de fichier ; symétriquement, no filetest 'access' le désactive. Cette fonctionnalité étendue de test de fichier n'est utilisée que lorsque l'opérande de l'opérateur (ou, si vous préférez, l'argument de la fonction unaire) est un véritable nom de fichier, et non un handle de fichier.

31-11. use integer

 
Sélectionnez
use integer;
$x=10 / 3;
# $x vaut maintenant 3, et non 3.33333333333333333

Ce pragma de portée lexicale indique au compilateur d'utiliser des opérations entières à partir de ce point et jusqu'à la fin du bloc l'encadrant. Sur la plupart des machines, cela influence peu la majorité des calculs, mais sur celles qui ne disposent pas de coprocesseur arithmétique, cela peut entraîner une différence de performance dramatique.

Remarquez que ce pragma affecte certaines opérations numériques, pas les nombres eux-mêmes. Par exemple, si vous lancez ce code :

 
Sélectionnez
use integer;
$x = 1.8;
$y=$x + 1;
$z = -1.8;

vous vous retrouverez avec $x == 1.8, $y== 2 et $z == -1. Le cas de $z s'explique par le fait qu'un - unaire compte comme une opération, ainsi la valeur 1.8 est tronquée à un avant que son bit de signe soit inversé. De même, les fonctions qui attendent des nombres à virgule flottante, comme sqrt ou les fonctions trigonométriques, recevront et renverront toujours des nombres à virgule même sous use integer. Ainsi sqrt(1.44) vaut 1.2 mais 0 + sqrt(1.44) vaut maintenant seulement 1.

L'arithmétique entière native, telle qu'elle est fournie par votre compilateur C, est utilisée. Cela signifie que la propre sémantique de Perl pour les opérations arithmétiques peut ne pas être préservée. Une source d'ennuis fréquente est le modulo des nombres négatifs. Perl le calcule d'une façon, mais votre matériel peut le faire d'une autre manière :

 
Sélectionnez
% perl -le 'print (4 % -3)'
-2
% perl -Minteger -le 'print (4 % -3)'
1

31-12. use less

 
Sélectionnez
use less;        # AUCUN N'EST IMPLÉMENTÉ

use less 'CPU';
use less 'memory';
use less 'time';
use less 'disk';
use less 'fat';  # géant avec "use locale";

Actuellement non implémenté, ce pragma est destiné à donner un jour des indications au compilateur, au générateur de code ou à l'interpréteur pour activer certains équilibrages.

Il n'y a aucun mal à demander à utiliser moins (use less) de quelque chose alors que Perl ne sait pas comment réduire ce quelque chose à l'heure actuelle.

31-13. use lib

 
Sélectionnez
use lib "$ENV{HOME}/libperl";  # ajoute ~/libperl
no lib ".";                    # enlève cwd

Ce pragma simplifie la manipulation de @INC à la compilation. Il est généralement utilisé pour ajouter des répertoires supplémentaires dans le chemin de recherche de Perl pour qu'ensuite les instructions do, require et use trouvent les fichiers de bibliothèque qui ne se situent pas dans le chemin de recherche par défaut de Perl. Il est particulièrement important avec use, puisque ce dernier intervient également à la compilation et que l'affectation ordinaire de @INC (c'est-à-dire à l'exécution) arriverait trop tard.

Les paramètres de use lib sont ajoutés au début du chemin de recherche de Perl. Écrire use lib LISTE revient à peu près au même qu'écrire BEGIN { unshift(@INC, LISTE)}, mais use libLISTE inclut le support des répertoires spécifiques à une plate-forme. Pour chaque répertoire $rep donné dans sa liste d'arguments, le pragma list vérifie également si un répertoire nommé $rep/$nom_architecture/auto existe ou non. Si c'est le cas, le répertoire $rep/$nom_architecture/auto est supposé correspondre à un répertoire spécifique à la plate-forme et il est donc ajouté à @INC (devant $rep).

Pour éviter les ajouts redondants qui ralentissent les temps d'accès et gaspillent une petite quantité de mémoire, les entrées dupliquées qui restent dans @INC sont supprimées lorsque des entrées sont ajoutées.

Normalement, vous ne devez qu'ajouter des répertoires dans @INC. Si vous avez vraiment besoin d'enlever des répertoires de @INC, prenez garde à ne supprimer que ceux que vous avez vous-même ajoutés ou ceux dont vous êtes certains qu'ils ne sont pas nécessaires à d'autres modules dans votre programme. D'autres modules peuvent avoir ajouté dans votre tableau @INC des répertoires dont ils avaient besoin pour que leurs opérations soient correctement effectuées.

Le pragma no lib supprime de @INC toutes les instances de chaque répertoire nommé. Il détruit également tous les répertoires correspondants spécifiques à la plate-forme, tels que nous les avons décrits plus haut.

Lorsque le pragma lib est chargé, il sauvegarde la valeur courante de @INC dans le tableau @lib::ORIG_INC, afin de copier ce tableau dans le véritable @INC pour restaurer la valeur originale.

Même si @INC inclut généralement le répertoire courant, point (« . »), Ce n'est vraiment pas aussi utile que vous pouvez le penser. Premièrement, l'entrée point vient à la fin, pas au début. Ainsi les modules installés dans le répertoire courant ne prennent pas soudainement le dessus sur les versions globales au système. Vous pouvez écrire use lib "." si c'est ce que vous voulez vraiment. Plus ennuyeux, il s'agit du répertoire courant du processus Perl, et non du répertoire où le script a été installé, ce qui enlève toute fiabilité à cet ajout de « . ». Si vous créez un programme, plus quelques modules utilisés par ce programme, il marchera tant que vous développez, mais cela cessera lorsque vous ne le lancerez pas depuis le répertoire où se trouvent les fichiers.

Une solution pour cela est d'utiliser le module standard FindBin :

 
Sélectionnez
use FindBin;            # où le script a-t-il été installé ?
use lib $FindBin::Bin;  # utilise également ce répertoire pour lib

Le module FindBin essaie de deviner le chemin complet vers le répertoire où a été installé le programme du processus en train de tourner. N'utilisez pas ceci dans des objectifs de sécurité, car les programmes malveillants peuvent d'ordinaire le détourner en essayant suffisamment énergiquement. Mais à moins que vous n'essayiez intentionnellement de casser le module, il devrait marcher comme prévu. Le module procure une variable $Findbin::Bin (que vous pouvez importer) qui contient l'emplacement où le programme a été installé, tel que le module l'a deviné. Vous pouvez alors utiliser le pragma lib pour ajouter ce répertoire à votre tableau @INC, produisant ainsi un chemin relatif à l'exécutable.

Certains programmes s'attendent à être installés dans un répertoire bin et trouvent alors leurs modules de bibliothèque dans les fichiers « cousins » installés dans un répertoire lib au même niveau que bin. Par exemple, des programmes peuvent se trouver dans /usr/ local/apache/bin ou /opt/perl/bin et les bibliothèques dans /usr/local/apache/lib et /opt/perl/ lib. Ce code en tient soigneusement compte :

 
Sélectionnez
use FindBin qw(Bin);
use lib "$Bin/../lib";

Si vous vous retrouvez à spécifier le même use lib dans plusieurs programmes sans rapport les uns avec les autres, vous pouvez envisager de positionner à la place la variable d'environnement PERL5LIB. Voir la description de la variable d'environnement PERL5LIB au chapitre 19, L'interface de la ligne de commande.

 
Sélectionnez
# syntaxe pour sh, bash, ksh ou zsh
$ PERLLIB=$HOME/libperl; export PERL5LIB

# syntaxe pour csh ou tcsh
$ setenv PERL5LIB ~/libperl

Si vous voulez utiliser des répertoires optionnels uniquement pour ce programme sans changer son code source, regardez du côté de l'option de la ligne de commande -I :

 
Sélectionnez
% perl -I ~/libperl chemin-programme args

Voir le chapitre 19 pour plus d'informations sur l'emploi de -I dans la ligne de commande.

31-14. use locale

 
Sélectionnez
@x = sort @y;     # tri dans l'ordre ASCII
{
    use locale;
    @x = sort @y; # tri dans l'ordre défini par les locales
}
@x = sort @y;     # à nouveau tri dans l'ordre ASCII

Ce pragma de portée lexicale indique au compilateur d'activer (ou de désactiver, avec no locale) l'emploi des locales POSIX pour les opérations intrinsèques. L'activation des locales indique aux fonctions de conversions de casse (majuscule/minuscule) de Perl et au moteur de recherche de motifs de respecter l'environnement de votre langue, en autorisant les signes diacritiques(224), etc. Si ce pragma est actif et que votre bibliothèque C connaît les locales POSIX, Perl recherche la valeur de votre variable d'environnement LC_CTYPE pour les expressions régulières et LC_COLLATE pour les comparaisons de chaînes comme celles de sort.

Comme les locales sont plus une forme de nationalisation que d'internationalisation, l'emploi des locales peut interférer avec Unicode. Voir le chapitre 15 pour plus d'informations sur l'internationalisation.

31-15. use open

 
Sélectionnez
use open IN => ":crlf", OUT => ":raw";

Le pragma open déclare une ou plusieurs disciplines par défaut pour les opérations d'entrées/sorties. Chaque opérateur open et readpipe (c'est-à-dire qx// ou les apostrophes inverses) découvert à l'intérieur de la portée lexicale de ce pragma et qui ne spécifie pas ses propres disciplines utilisera celles déclarées par défaut. Ni open avec un ensemble explicite de disciplines, ni sysopen en toute circonstance, ne sont influencés par ce pragma.

Seules les deux disciplines :raw et :crlf sont actuellement implémentées (cependant au moment où nous écrivons cela, nous espérons qu'une discipline :utf8 le soit également bientôt). Sur les systèmes ancestraux qui font la distinction entre ces deux modes de conversions lors de l'ouverture de fichiers, la discipline :raw correspond au « mode binaire » et :crlf au « mode texte ». (Ces deux disciplines n'ont actuellement aucun effet sur les plates-formes où binmode n'en a pas non plus, mais seulement pour le moment ; voir la fonction open au chapitre 29, Fonctions, pour une description plus détaillée des sémantiques que nous espérons en ce qui concerne les diverses disciplines.)

Le support exhaustif des disciplines d'entrées/sorties n'est pas encore implémenté à ce jour. Lorsqu'elles seront enfin supportées, ce pragma servira comme l'une des interfaces pour déclarer les disciplines par défaut pour toutes les entrées/sorties. À ce moment-là, les disciplines par défaut déclarées avec ce pragma seront accessibles par le biais de la discipline spéciale nommée « :DEFAULT » et exploitables à l'intérieur des constructeurs de handles qui autorisent la spécification de disciplines. Cela rendra possible l'empilement de nouvelles disciplines par-dessus celles par défaut.

 
Sélectionnez
open (HF, "<:para :DEFAULT", $fichier)
    or die "impossible d'ouvrir $fichier : $!";

Lorsqu'il sera complet, le support des disciplines d'entrées/sorties permettra à toutes les disciplines supportées de fonctionner sur toutes les plates-formes.

31-16. use overload

Dans le module Nombre :

 
Sélectionnez
package Nombre;
use overload "+" => \&mon_addition;
             "-" => \&ma_soustraction;
            "*=" => \&mon_produit_par;

Dans votre programme :

 
Sélectionnez
use Nombre;
$a = new Nombre 57;
$b=$a +5;

Les opérateurs internes fonctionnent bien avec des chaînes et des nombres, mais n'ont que peu de sens lorsqu'on les applique à des références d'objets (puisque, contrairement à C ou à C++, Perl ne permet pas de faire de l'arithmétique de pointeur). Le pragma overload vous laisse redéfinir les significations de ces opérations internes lorsque vous les appliquez à des objets de votre cru. Dans l'exemple précédent, l'appel au pragma redéfinit trois opérations sur des objets Nombre : l'addition appellera la fonction Nom-bre::mon_addition, la soustraction appellera la fonction Nombre::ma_soustraction et l'opérateur d'assignement accompagné d'une multiplication appellera la méthode mon_produit_par de la classe Nombre (ou de l'une de ses classes de base). Nous disons que ces opérateurs sont surchargés (overloaded), car des significations supplémentaires les recouvrent (et non parce qu'ils ont trop de significations -quoique cela peut également être le cas).

Pour plus d'informations sur la surcharge, voir le chapitre 13, Surcharge.

31-17. use re

Ce pragma contrôle l'utilisation des expressions régulières. On peut l'invoquer de quatre façons : « taint » et « eval », qui ont une portée lexicale, plus « debug » et « debugcolor » qui n'en ont pas.

 
Sélectionnez
use re 'taint';
# Le contenu de $corresp est marqué si $gribouille était aussi marqué.
($corresp) = ($gribouille =~ /(.*)$/s);

# Permet l'interpolation de code :
use re 'eval';
$motif = '(?{ $var = 1 })';     # exécution de code inséré
/alpha${motif}omega/;           # n'échouera pas à moins d'être lancé
                                # avec -T et que $motif soit marqué

use re 'debug';                 # comme "perl -Dr"
/^(.*)$/s;                      # affichage d'informations de débogage
                                # durant la compilation et l'exécution

use re 'debugcolor'             # comme 'debug', mais avec un affichage
                                # en couleur

Lorsque use re 'taint' est actif et qu'une chaîne marquée est la cible de l'expression régulière, les variables numérotées de l'expression régulière et les valeurs renvoyées par l'opérateur m// dans un contexte de liste sont également marquées. Ceci est très utile lorsque les opérations d'expressions régulières sur des données marquées ne sont pas vouées à extraire des sous-chaînes sécurisées, mais à effectuer d'autres transformations. Voir la discussion sur le marquage au chapitre 23.

Lorsque use re 'eval' est actif, une expression régulière a le droit de contenir des assertions exécutant du code Perl, qui sont de la forme (?{...}), même si l'expression régulière contient des variables interpolées. L'exécution des segments de code résultant de l'interpolation de variables à l'intérieur des expressions régulières n'est pas habituellement permise pour des raisons de sécurité : vous ne voulez pas que des programmes qui lisent des motifs depuis des fichiers de configuration, des arguments de la ligne de commande ou des champs de formulaires CGI, se mettent subitement à exécuter un code arbitraire s'ils ne sont pas conçus pour s'attendre à cela. Cet emploi du pragma permet uniquement aux chaînes non marquées d'être interpolées ; les données marquées causeront toujours la levée d'une exception (si vous activez la vérification des marquages).

Voir également le chapitre 5, Correspondance de motifs et le chapitre 23.

À l'intention de ce pragma, l'interpolation d'expressions régulières précompilées (produites par l'opérateur qr//) n'est pas considérée comme une interpolation de variable. Néanmoins, lorsque vous construisez le motif qr//, use re 'eval' doit être actif si l'une de ses chaînes interpolées contient des assertions de code. Par exemple :

 
Sélectionnez
$code = '(?{ $n++ })';         # assertion de code
$chaine = '\b\w+\b' . $code;   # construit la chaîne à interpoler
$ligne =~ /$chaine/;           # ceci a besoin de use re 'eval'
$motif = qr/$chaine/;          # ceci également
$ligne =~ /$motif/;            #, mais pas ceci

Avec use re 'debug', Perl émet des messages de débogage à la compilation et à l'exécution d'expressions régulières. L'affichage est identique à celui obtenu en lançant un « débogueur Perl » (l'un de ceux compilés en passant -DDEBUGGING au compilateur C) et en exécutant alors votre programme Perl avec l'option de la ligne de commande de Perl -Dr. Selon la complexité de votre motif, l'affichage résultant peut vous noyer. L'appel de use re 'debugcolor' permet un affichage plus coloré qui peut s'avérer utile, pourvu que votre terminal comprenne les séquences de couleurs. Positionner votre variable d'environnement PERL_RE_TC avec une liste de propriétés termcap(5) pertinentes, séparées par des virgules, pour faire ressortir l'affichage. Pour plus de détails, voir le chapitre 20, Le débogueur Perl.

31-18. use sigtrap

 
Sélectionnez
use sigtrap;
use sigtrap qw(stack-trace old-interface-signals); # idem
use sigtrap qw(BUS SEGV PIPE ABRT);
use sigtrap qw(die INT QUIT);
use sigtrap qw(die normal-signals);
use sigtrap qw(die untrapped normal-signals);
use sigtrap qw(die untrapped normal-signals stack-trace any error-signals);

Le pragma sigtrap installe pour vous quelques gestionnaires de signaux simples pour vous éviter de vous en inquiéter. Ceci est très utile dans les situations où les signaux non interceptés causeraient des dysfonctionnements dans votre programme; comme lorsque vous avez des blocs END {}, des destructeurs d'objets ou d'autres traitements à lancer à la fin de votre programme, quelle que soit la façon dont il se termine.

Le pragma sigtrap fournit deux gestionnaires de signaux simples que vous pouvez utiliser. L'un apporte à Perl une trace de la pile et l'autre lance une exception ordinaire via die. Vous pouvez aussi fournir votre propre gestionnaire au pragma pour qu'il l'installe. Vous pouvez spécifier des ensembles de signaux prédéfinis à intercepter ; vous pouvez également donner votre propre liste explicite de signaux. Le pragma peut optionnellement installer des gestionnaires uniquement pour les signaux qui n'auraient sinon pas été gérés.

Les arguments passés à use sigtrap sont traités dans l'ordre. Lorsqu'un nom de signal fourni par l'utilisateur ou le nom d'un des ensembles de signaux prédéfinis de sigtrap est rencontré, un gestionnaire est immédiatement installé. Lorsqu'il y a une option, celle-ci n'affecte que les gestionnaires installés ensuite en traitant la liste d'arguments.

31-18-a. Gestionnaires de signaux

Ces options ont pour effet de décider quel gestionnaire sera utilisé pour les signaux installés ensuite :

stack-trace

  • Ce gestionnaire fourni par le pragma affiche une trace de la pile d'exécution Perl vers STDERR et tente alors de faire une copie du cœur du programme (core dump). Il s'agit du gestionnaire de signaux par défaut.

die

  • Ce gestionnaire fourni par le pragma appelle die via Carp::croak avec un message indiquant le signal reçu.

handler VOTRE_GESTIONNAIRE

  • VOTRE_GESTIONNAIRE sera utilisé comme gestionnaire pour les signaux installés ensuite. VOTRE_GESTIONNAIRE peut être n'importe quelle valeur valide pour un assignement de %SIG. Souvenez-vous que le fonctionnement correct de beaucoup d'appels de la bibliothèque C (en particulier les appels d'entrées/sorties standards) n'est pas garanti à l'intérieur d'un gestionnaire de signaux. Pis encore, il est difficile de deviner quels morceaux du code de la bibliothèque C sont appelés depuis tel ou tel morceau du code Perl. (D'un autre côté, nombre de signaux que sigtrap intercepte sont un peu vicieux — ils vous feront tourner en bourrique de toute façon, alors ça ne coûte pas grand-chose d'essayer de faire quelque chose, n'est-ce pas?)
31-18-b. Listes prédéfinies de signaux

Le pragma sigtrap inclut quelques listes prédéfinies de signaux à intercepter :

normal-signals

  • Il s'agit des signaux qu'un programme peut normalement s'attendre à rencontrer et qui le font, par défaut, se terminer. Ce sont les signaux HUP, INT, PIPE et TERM.

error-signals

  • Il s'agit des signaux qui d'ordinaire indiquent un sérieux problème avec l'interpréteur Perl ou avec votre programme. Ce sont les signaux ABRT, BUS, EMT, FPE, KILL, QUIT, SEGV, SYS et TRAP.

old-interface-signals

  • Il s'agit des signaux qui sont interceptés par défaut sous une ancienne version de l'interface de sigtrap. Ce sont les signaux ABRT, BUS, EMT, FPE, KILL, PIPE, QUIT, SEGV, SYS, TERM et TRAP. Si aucun signal ou aucune liste de signaux n'est passé à use sigtrap, on utilise cette liste.

Si votre plate-forme n'implémente pas un signal particulier cité dans les listes prédéfinies, le nom de ce signal sera discrètement ignoré. (Le signal lui-même ne peut pas être ignoré, car il n'existe pas.)

31-18-c. Autres arguments de sigtrap

untrapped

  • Ce token supprime les gestionnaires pour tous les signaux listés ultérieurement s'ils ont déjà été interceptés ou ignorés.

any

  • Ce token installe des gestionnaires pour tous les signaux listés ultérieurement. Il s'agit du comportement par défaut.

signal

  • Tout argument qui ressemble à un nom de signal (c'est-à-dire qui correspond au motif /^[A-Z][A-Z0-9]*$/ enjoint à sigtrap de gérer ce signal.

nombre

  • Un argument numérique requiert que le numéro de version du pragma sigtrap soit au moins nombre. Ceci fonctionne exactement comme la plupart des modules ordinaires qui ont une variable de paquetage $VERSION.
 
Sélectionnez
% perl -Msigtrap -le 'print $sigtrap::VERSION'
1.02
31-18-d. Exemples de sigtrap

Fournit une trace de la pile pour les signaux utilisant l'ancienne interface :

 
Sélectionnez
use sigtrap;

Idem, mais plus explicite :

 
Sélectionnez
use sigtrap qw(stack-trace old-interface-signals);

Fournit une trace de la pile uniquement pour les quatre signaux listés :

 
Sélectionnez
use sigtrap qw(BUS SEGV PIPE ABRT);

Meurt (via die) sur réception du signal INT ou QUIT :

 
Sélectionnez
use sigtrap qw(die INT QUIT);

Meurt (via die) sur réception de l'un des signaux HUP, INT, PIPE ou TERM : use

 
Sélectionnez
sigtrap qw(die normal-signals);

Meurt (via die) sur réception de HUP, INT, PIPE ou TERM — à cela près qu'on ne change pas le comportement pour les signaux qui ont déjà été interceptés ou ignorés ailleurs dans le programme :

 
Sélectionnez
use sigtrap qw(die untrapped normal-signals);

Meurt (via die) sur réception de n'importe quel signal « normal-signals » non intercepté actuellement ; de plus, fournit une trace arrière de la pile d'exécution sur réception de l'un des signaux « error-signals » :

 
Sélectionnez
use sigtrap qw(die untrapped normal-signals stack-trace any error-signals);

Installe la routine mon_gestionnaire comme gestionnaire pour les signaux « normalsignals » :

 
Sélectionnez
use sigtrap 'handler' => \&mon_gestionnaire, 'normal-signals';

Installe la routine mon_gestionnaire comme gestionnaire pour les signaux « normalsignals » ; de plus, fournit une trace arrière de la pile d'exécution sur réception de l'un des signaux « error-signals » :

 
Sélectionnez
use sigtrap qw(handler mon_gestionnaire normal-signals stack-trace
                error-signals);

31-19. use strict

 
Sélectionnez
use strict;        # Installe les trois restrictions.

use strict "vars"; # Les variables doivent être prédéclarées.
use strict "refs"; # Les références symboliques sont interdites.
use strict "subs"; # Les chaînes brutes doivent être entre guillemets.

use strict;        # Installe toutes les restrictions
no strict "vars";  # puis renonce à l'une d'entre elles.

Ce pragma de portée lexicale modifie quelques règles basiques à propos de ce que Perl considère comme étant du code légal. Quelquefois, ces restrictions semblent trop strictes pour de la programmation occasionnelle, comme lorsque vous ne faites qu'essayer de programmer à la hâte un filtre de cinq lignes. Plus votre programme est gros, plus vous devez être strict avec lui.

Actuellement, vous devez être strict avec trois choses : subs, vars et refs. Si aucune liste d'importation n'est fournie, les trois restrictions sont prises en compte.

31-19-a. strict 'refs'

Cet exemple génère une erreur à l'exécution si vous utilisez des références symboliques, intentionnellement ou pas. Voir le chapitre 8, Références pour plus d'informations.

 
Sélectionnez
use strict 'refs';

$ref = \$truc; # Enregistre une référence "réelle" (en dur).
print $$ref;   # Déréférencement OK.

$ref = "truc"; # Enregistre le nom d'une variable globale (de paquetage).
print $$ref;   # FAUX, erreur à l'exécution avec strict refs.

Les références symboliques sont suspectes pour diverses raisons. Il est étonnamment aisé, même pour des programmeurs bien intentionnés, de les invoquer accidentellement ; strict 'refs' l'empêche. Au contraire des références réelles, les références symboliques ne peuvent se référer qu'à des variables globales. Elles ne possèdent pas de compteur de références. Il existe souvent un meilleur moyen d'accomplir ce que vous faites : au lieu de référencer un symbole dans une table de symboles globale, utilisez un hachage pour sa propre minitable de symboles. C'est plus efficace, plus lisible et moins sujet à engendrer des erreurs.

Néanmoins, certains types de manipulations valides nécessitent vraiment un accès direct à la table de symboles globale du paquetage pour les noms de variables et de fonctions. Par exemple, il se peut que vous vouliez examiner la liste @EXPORT de la super-classe @ISA d'un paquetage donné dont vous ne connaissez pas le nom à l'avance. Ou vous pourriez vouloir installer toute une kyrielle d'appels de fonctions qui seraient toutes des alias de la même fermeture. C'est seulement là que les références symboliques sont les plus utiles, mais pour les utiliser alors que use strict est actif, vous devez d'abord annuler la restriction « ref » :

 
Sélectionnez
# construit un groupe d'accesseurs pour les attributs
for my $nom_meth (qw/nom grade matricule/) {
    no strict 'refs';
    *$nom_meth = sub { $_[0]->{ __PACKAGE__ . $nom_meth };
}

31-20. strict 'vars'

Dans cette restriction, une erreur de compilation est déclenchée si vous essayez d'accéder à une variable qui n'est pas conforme à au moins un de ces critères :

  • Prédéfinie par Perl, comme @ARGV, %ENV et toutes les variables globales avec des signes de ponctuation comme $. ou $_.
  • Déclarée avec our (pour une variable globale) ou my (pour une variable lexicale).
  • Importée depuis un autre paquetage. (Le pragma use vars simule une importation, mais utilisez our à la place.)
  • Pleinement qualifiée en utilisant le nom de son paquetage et le double deux-points séparateur de paquetage.

L'emploi seul d'un opérateur local n'est pas suffisant pour rendre heureux, use strict 'vars' car, malgré son nom, cet opérateur ne change pas le fait qu'une variable nommée soit globale ou non. Il donne seulement à la variable une nouvelle valeur temporaire durant un bloc lors de l'exécution. Vous devrez toujours employer our pour déclarer une variable globale ou my pour déclarer une variable lexicale. Vous pouvez toutefois localiser un our :

 
Sélectionnez
local our $loi = "martiale";

Les variables globales prédéfinies par Perl sont dispensées de ces exigences. Ceci s'applique aux variables globales de tout le programme (celles forcées dans le paquetage main comme @ARGV ou $_) et aux variables par paquetage comme $a ou $b, qui sont normalement utilisée par la fonction sort. Les variables par paquetage utilisées par les modules comme Exporter ont toujours besoin d'être déclarées en utilisant our :

 
Sélectionnez
our @EXPORT_OK = qw(nom grade matricule);

31-21. strict 'subs'

Cette restriction oblige Perl à traiter les mots simples comme des erreurs de syntaxe. Un mot simple (bareword ou bearword dans certains dialectes) est un nom simple ou un identificateur qui n'a aucune autre interprétation forcée par le contexte. (Le contexte est souvent forcé par la proximité d'un mot clef ou d'un token ou par la prédéclaration du mot en question.) Historiquement, les mots simples étaient interprétés comme des chaînes sans guillemets ou apostrophes. Cette restriction rend cette interprétation illégale. Si vous avez l'intention de l'utiliser en tant que chaîne, mettez-la entre guillemets ou entre apostrophes. Si vous avez l'intention de l'utiliser en tant que fonction, prédéclarez-la ou employez des parenthèses.

Comme cas particulier de contexte forcé, souvenez-vous qu'un mot qui apparaît entre des accolades ou du côté gauche de l'opérateur => compte comme s'il était entre apostrophes et n'est donc pas sujet à cette restriction.

 
Sélectionnez
use strict 'subs';

$x = n_importe_quoi;                # FAUX : erreur de mot simple !
$x = n_importe_quoi();              # Par contre, cela marche toujours.

sub n_importe_quoi;                 # Prédéclaration de fonction.
$x = n_importe_quoi;                # Maintenant OK.

# Ces utilisations sont permises, car => met entre apostrophes :
%hachage = (rouge => 1, vert => 2, bleu => 3);

$num_rouge = $hachage{rouge};       # Ok, les accolades mettent entre
                                    # apostrophes ici.

#, Mais pas celles-ci :
@nums = @hachage{bleu, vert};      # Faux : erreur de mot simple.
@nums * @hachage{"bleu", "vert"};  # Ok, les mots sont maintenant entre
                                   # guillemets.
@nums = @hachage{qw/bleu vert/};   # Idem.

31-22. use subs

 
Sélectionnez
use subs qw/am stram gram/;
@x = am 3..10;
@x = gram stram @x;

Ce pragma prédéclare tous les noms de la liste d'arguments comme étant des sous-programmes standards. L'avantage ici est que vous pouvez maintenant utiliser ces fonctions sans parenthèses en tant qu'opérateurs de listes, exactement comme si vous les aviez déclarées vous-mêmes. Ce n'est pas forcément aussi utile que des déclarations complètes, car cela ne permet pas d'utiliser des prototypes ou des attributs comme dans :

 
Sélectionnez
sub am(@);
sub stram(\@) : locked;
sub gram($) : lvalue;

Puisqu'il est basé sur le mécanisme d'importation standard, le pragma use subs n'a pas de portée lexicale, mais une portée de paquetage. C'est-à-dire que les déclarations sont effectives pour la totalité du fichier dans lequel elles apparaissent, mais seulement pour le paquetage courant. Vous ne pouvez pas annuler de telles déclarations avec no subs.

31-23. use vars

 
Sélectionnez
use vars qw($bricole @refait %vu);

Ce pragma, autrefois utilisé pour déclarer une variable globale, est maintenant quelque peu déprécié en faveur du modificateur our. La déclaration précédente s'effectue mieux en utilisant :

 
Sélectionnez
our($bricole, @refait, %vu};

ou même :

 
Sélectionnez
our $bricole = "F";
our @refait = "A" .. $bricole;
our %vu = ();

Peu importe que vous utilisiez l'une ou l'autre de ces possibilités, rappelez-vous qu'elles portent toutes sur des variables globales de paquetage, et non sur des variables lexicales ayant la portée du fichier.

31-24. use warnings

 
Sélectionnez
use warnings;  # Revient à importer "all".
no warnings;   # Revient à annuler l'importation de "all".

use warnings::register; 
if (warnings::enabled()) {
    warnings::warn("un avertissement"); 
}

if (warnings::enabled("void")) {
    warnings::warn("void", "un avertissement"); 
}

Ce pragma de portée lexicale permet un contrôle souple sur les avertissements internes de Perl, à la fois ceux émis par le compilateur et ceux provenant du système d'exécution.

Autrefois, le seul contrôle que vous aviez sur le traitement des avertissements de votre programme se faisait par le biais de l'option de la ligne de commande -w ou de la variable $^W. Bien qu'utile, ces solutions tendaient à faire du tout-ou-rien. L'option -w active des avertissements dans des morceaux de code que vous pouvez ne pas avoir écrits, ce qui est parfois problématique pour vous et embarrassant pour l'auteur original. L'emploi de $^W, soit pour activer, soit pour désactiver des blocs de code, peut s'avérer moins qu'optionnel, car il ne fonctionne que durant l'exécution et non pendant la compilation.(225) Un autre problème est que cette variable globale à tout le programme possède une portée dynamique et non lexicale. Cela signifie que si vous l'activez dans un bloc et qu'ensuite vous appelez à partir de là un autre code, vous risquez ici encore d'activer des avertissements dans du code qui n'est pas développé avec exactement de tels standards à l'esprit.

Le pragma warnings contourne ces limitations en possédant une portée lexicale, des mécanismes durant la compilation qui permettent un contrôle plus fin sur l'endroit où les avertissements peuvent ou ne peuvent pas être déclenchés. Une hiérarchie de catégories d'avertissements (voir la figure 31-1) a été définie pour permettre aux groupes d'avertissements d'être activés ou désactivés séparément les uns des autres. (La catégorisation exacte est expérimentale et sujette à modifications.) Ces catégories peuvent être combinées en passant des arguments multiples à use ou no :

Image non disponible
Catégories des avertissements Perl
 
Sélectionnez
use warnings qw(void redefine);
no warnings qw(io syntax untie);

Si des instances multiples du pragma warnings sont actives pour un groupe donné, leurs effets se cumulent :

 
Sélectionnez
use warnings "void"; # Seuls les avertissements "void" sont actifs.
...
use warnings "io";   # Les avertissements "void" et "io" sont
                     # maintenant tous deux actifs.
...
no warnings "void";  # Seuls les avertissements "io" sont maintenant
                     # actifs.

Pour donner des erreurs fatales pour tous les avertissements activés par un pragma warnings particulier, utilisez le mot FATAL devant la liste d'importation. Ceci est très utile lorsque vous aimez mieux qu'une certaine condition, qui d'ordinaire n'aurait causé qu'un avertissement, arrête votre programme. Supposez par exemple que vous considériez l'emploi d'une chaîne invalide en tant que nombre (qui normalement aurait donné une valeur de 0) si incorrect que vous vouliez que cet acte effronté tue votre programme. Pendant que vous y êtes, vous décidez que l'utilisation de valeurs non initialisées en lieu et place de chaînes réelles ou de valeurs numériques doit également être la cause d'un suicide immédiat :

 
Sélectionnez
{
    use warnings FATAL => qw(numeric unitialized);
    $x =$y +$z;
}

Maintenant, si $y ou $z ne sont pas initialisées (c'est-à-dire, contiennent la valeur scalaire spéciale undef) ou si elles contiennent des chaînes qui ne se convertissent pas proprement en valeurs numériques, au lieu de continuer gentiment son chemin ou tout au plus d'émettre une petite complainte si vous aviez activé -w, votre programme lèvera maintenant une exception. (Pensez à cela comme du Perl tournant en mode Python.) Si vous n'interceptez pas les exceptions, elles causeront une erreur fatale. Le texte de l'exception est le même que celui qui serait normalement apparu dans le message d'avertissement.

Le pragma warnings ignore l'option de la ligne de commande -w et la valeur de la variable $^W ; les configurations du pragma sont prioritaires. Toutefois, le drapeau -W de la ligne de commande passe outre le pragma, en activant totalement les avertissements dans tous le code à l'intérieur de votre programme, y compris le code chargé avec do, require ou use. En d'autres termes, avec -W, Perl prétend que chaque bloc de votre programme possède un pragma use warnings 'all'. Pensez-y comme un lint(1) pour les programmes Perl. (Mais voyez également la documentation en ligne du module B::Lint.) Le drapeau -X de la ligne de commande fonctionne à l'inverse. Il prétend que chaque bloc a un no warnings 'all' activé.

Plusieurs fonctions sont fournies pour assister les auteurs de modules qui veulent que les fonctions de leur module se comportent comme les fonctions internes en respectant la portée lexicale de l'appelant (c'est-à-dire, de manière à ce que les utilisateurs du module puissent lexicalement activer ou désactiver les avertissements que le module pourrait émettre) :

warnings::register

  • Enregistre le nom du module courant comme une nouvelle catégorie d'avertissements, afin que les utilisateurs du module puissent en stopper les avertissements.

warnings::enabled(CATEGORIE)

  • Renvoie vrai si la catégorie CATEGORIE est activée dans la portée lexicale du module appelant. Sinon, renvoie faux. Si CATEGORIE n'est pas fournie, le nom du paquetage courant est utilisé.

warnings::warn(CATEGORIE, MESSAGE)

  • Si le module appelant n'a pas positionné CATEGORIE à « FATAL », affiche MESSAGE sur STDERR. Si le module appelant a positionné CATEGORIE à« FATAL », affiche MESSAGE sur STDERR, puis meurt. Si CATEGORIE n'est pas fournie, le nom du paquetage courant est utilisé.

32. Modules standards

L'édition précédente de ce livre couvrait de manière très complète et définitive tous les modules faisant partie de la distribution standard de Perl. Si nous avions refait la même chose ici, vous auriez payé de livre le double, sans parler de ce que vous auriez dû payer au chiropracteur après avoir essayé de porter le livre jusqu'à chez vous. Ces dernières années, de plus en plus de modules ont été inclus dans la distribution standard ; nous en sommes à ce jour à environ deux cents. Certains d'entre eux, comme CGI, proposent eux-mêmes une documentation remarquablement approfondie. Et si vous utilisez la distribution de Perl ActiveState, votre bibliothèque standard est encore plus raffinée.

Ainsi, nous vous offrons à la place une énumération complète des modules standards, classés par type, accompagnés d'une brève description. Puis, cerise sur le gâteau, nous avons sélectionné quelques-uns de nos modules favoris, vous en donnant des exemples d'utilisation classique, suivis d'une courte description de leur fonctionnement, juste pour que vous y goûtiez un peu. Les descriptions sont suggestives plutôt que complètes et quasiment tous les modules ont d'autres fonctionnalités que celles que nous montrons. Toutefois, une documentation complète de tous les modules standards est incluse dans chaque distribution de Perl, vous n'avez donc qu'à rechercher les détails sur votre propre système en utilisant le programme perldoc, la commande man(1) de votre système ou votre navigateur préféré. Voir la section Documentation en ligne de la préface. Demandez à votre expert maison si vous ne trouvez pas les documents, car ils sont quasi certainement quelque part sur votre système. Et même si ils n'y sont pas, vous pouvez toujours les lire au format pod directement dans les modules eux-mêmes, car toute la documentation des modules est insérée dans le fichier de module (.pm) lui correspondant et le format pod a été conçu pour être assez lisible. (Pas comme, disons, HTML.)

32-1. Listes par type

Le nom des modules ordinaires commence par une majuscule. Des noms en minuscules indiquent des pragmas dont vous trouverez la documentation au chapitre 31, Modules de pragmas, plutôt que dans le présent chapitre.

32-1-a. Types de données

Ces modules étendent le système de typage de Perl (ou plutôt ses lacunes) de diverses manières.

Module

Description

Class::Struct

Crée des classes d'objets Perl ressemblant à struct.

constant

Déclare des scalaires et des listes constantes.

integer

Force Perl à faire de l'arithmétique avec des entiers au lieu de nombres à virgule flottante.

Math::BigFloat

Calcule avec des nombres à virgule flottante d'une longueur arbitraire.

Math::BigInt

Calcule avec des entiers de longueur arbitraire.

Math::Complex

Calcule avec des nombres complexes et les fonctions mathématiques associées.

Math::Trig.

Charge beaucoup de fonctions trigonométriques

overload

Surcharge les opérateurs Perl sur des objets.

Symbol

Manipule les tables de symboles de Perl et génère des types globs anonymes.

Time:Local

Calcule efficacement la date et l'heure origine selon locatime ou gmtime.

32-1-b. Traitement des chaînes, traitement de textes linguistiques, analyse et recherche

Ces modules agissent avec (ou sur) des textes.

Module

Description

Search::Dict

Effectue une recherche binaire d'une chaîne dans un fichier texte trié.

Text::Abbrev

Crée une table d'abréviations à partir d'une liste.

Text::ParseWords

Analyse du texte dans une liste de tokens ou dans un tableau de tableaux.

Text::Soundex

Utilise l'algorithme Soundex de Knuth.

Text::Tabs

Développe ou réduit les tabulations comme expand(1) ou unexpand(1).

Text::Wrap

Équilibre des lignes pour former des paragraphes simples.

32-1-c. Traitement des options, arguments, paramètres et fichiers de configurations

Ces modules traitent votre ligne de commande.

Module

Description

Getopt::Long

Traite des options étendues de la ligne de commande dans une forme longue (-xyz).

Getopt::Std

Traite des options d'un seul caractère avec regroupement d'options.

32-1-d. Noms de fichier, systèmes de fichiers et verrouillage de fichiers

Ces modules fournissent des méthodes d'accès aux fichiers sur plusieurs plates-formes.

Module

Description

Cwd

Obtient le chemin du répertoire de travail courant.

File::Basename

Décompose de manière portable le nom d'un chemin en ses composants : répertoire, nom de base et extension.

File::CheckTree

Lance plusieurs tests de fichiers sur un ensemble d'arborescences de répertoires.

File::Compare

Compare de manière portable les contenus de fichiers ou de handles de fichiers.

File::Copy

Copie de manière portable des fichiers ou des handles de fichiers ou déplace des fichiers.

File::DosGlob

Réalise des globs dans le style Microsoft.

File::Find

Parcourt une arborescence de fichiers comme find(1).

File::Glob

Utilise des globs dans le style Unix.

File::Path

Crée ou supprime de manière portable une série de répertoires.

File::Spec

Utilise des opérations portables sur les fichiers (interface orientée objet).

File::Spec::Functions

Utilise des opérations portables sur les fichiers (interface orientée objet).

File::Spec::Mac

Utilise des opérations sur les fichiers pour Mac OS.

File::Spec::OS2

Utilise des opérations sur les fichiers pour OS/2.

File::Spec::Unix

Utilise des opérations sur les fichiers pour Unix.

File::Spec::VMS

Utilise des opérations sur les fichiers pour VMS.

File::Spec::Win32

Utilise des opérations sur les fichiers pour Microsoft.

File::stat

Supplante les fonctions stat et lstat avec une interface utilisant des méthodes.

32-1-e. Utilitaires pour les handles de fichiers, les handles de répertoires et les flux d'entrées/sorties

Ces modules fournissent un accès orienté objet aux fichiers, aux répertoires et aux IPC.

Module

Description

DirHandle

Utilise des méthodes objets pour les handles de répertoires.

FileCache

Garde plus de fichiers ouverts simultanément en écriture que votre système ne le permet.

FileHandle

Utilise des méthodes objets pour les handles de fichiers.

IO

Fournit un frontal pour charger tous les modules IO::Dir, IO::File, IO::Handle, IO::Pipe, IO::Seekable et IO::Socket.

IO::Dir

Utilise des méthodes objets pour les handles de répertoires.

IO::File

Utilise des méthodes objets en rapport avec les fichiers pour les handles de fichiers.

IO::Handle

Utilise des méthodes objets génériques pour les handles de fichiers/

IO::Pipe

Utilise des méthodes objets pour les pipes.

IO::Poll

Fournit une interface orientée objet à l'appel système poll(2).

IO::Seekable

Utilise des méthodes objets pour les objets d'entrées/sorties dans lesquels on peut faire des recherches (avec seek).

IO::Select

Utilise une interface orientée objet facilitant l'appel système select(2).

SelectSaver

Sauvegarde et restaure les handles de fichiers sélectionnés.

32-1-f. Internationalisation et locales

Ces modules vous aident dans vos activités extra-américaines.

Module

Description

bytes

Force l'ancienne sémantique orientée octets.

charnames

Définit les noms de caractères utilisés dans les séquences d'échappements \N{nom} pour les chaînes littérales.

I18N::Collate

Compare des données scalaires de 8 bits selon la locale courante (déprécié).

locale

Utilise ou évite les locales POSIX pour les opérations internes.

utf8

Bascule explicitement sur le support UTF-8 et Unicode.

32-1-g. Interfaces au système d'exploitation

Ces modules ajustent votre interface au système d'exploitation.

Module

Description

Fcntl

Charge les définitions de fcntl.h de la bibliothèque C en tant que constantes Perl.

filetest

Contrôle les opérateurs de tests de fichiers (-r, -w, etc.) pour les systèmes non traditionnels.

open

Positionne les disciplines par défaut pour les appels à la fonction open.

POSIX

Utilise l'interface Perl à POSIX 1003.1.

Shell

Lance des commandes shells de manière transparente à l'intérieur de Perl.

sigtrap

Active une gestion simple des signaux.

Sys::Hostname

Essaye de manière portable tous les moyens imaginables pour déterminer le nom de l'hôte courant.

Sys::Syslog

Utilise les fonctions syslog(3) de la bibliothèque C.

Time::gmtime

Supplante la fonction interne gmtime par une interface méthodes.

Time::localtime

Supplante la fonction interne localtime par une interface méthodes.

Time::tm

Fournit l'objet interne utilisé par Time::gmtime et Time::localtime.

User::grent

Supplante les fonctions internes getgr* par une interface méthodes.

User::pwent

Supplante les fonctions internes getpw* par une interface méthodes.

32-1-h. Communication réseau et interprocessus

Ces modules fournissent des interfaces abstraites à côté des interfaces basiques que nous avons décrites au chapitre 16, Communication interprocessus.

Module

Description

IO::Socket

Utilise une interface orientée objet générique pour les communications sur des sockets.

IO::Socket::INET

Utilise une interface orientée objet pour les sockets du domaine Internet.

IO::Socket::UNIX

Utilise une interface orientée objet pour les sockets du domaine Unix (locales).

IPC::Msg

Utilise des méthodes objets pour travailler avec les messages System V (classe objet SysV Msg IPC).

IPC::Open2

Ouvre un processus en lecture et écriture simultanées.

IPC::Open3

Ouvre un processus pour lire, écrire et gérer les erreurs.

IPC::Semaphore

Utilise des méthodes objets pour les sémaphores System V.

IPC::SysV

Définit des constantes pour tous les mécanismes des IPC System V.

Net::hostent

Supplante les fonctions internes gethost* par une interface méthodes.

Net::netent

Supplante les fonctions internes getnet* par une interface méthodes.

Net::Ping

Vérifie si un hôte distant est joignable.

Net::protoent

Supplante les fonctions internes getproto* par une interface méthodes.

Net::servent

Supplante les fonctions internes getserv* par une interface méthodes.

Socket

Charge les définitions et les fonctions manipulant des structures de socket.h de la bibliothèque C.

32-1-i. World Wide Web

Ces modules interfacent le WWW. Vous devez en avoir entendu parler.

Module

Description

CGI

Accède aux formulaires CGI et à la génération performante et automatique de HTML.

CGI::Apache

Fait fonctionner vos scripts CGI sous l'API Perl-Apache.

CGI::Carp

Écrit dans le journal d'erreurs CGI de httpd(8) (ou d'autres).

CGI::Cookie

Lit et écrit des cookies HTTP.

CGI::Fast

Utilise le protocol Fast CGI.

CGI::Pretty

Produit du code HTML agréablement formaté.

CGI::Push

Réalise des scripts CGI server-push (N.d.T. : sollicités par le serveur).

32-1-j. Interfaces DBM

Ces modules chargent diverses bibliothèques de gestion de bases de données.

Module

Description

AnyDBM_File

Fournit une infrastructure pour de multiples bibliothèques DBM.

DB_File

Fournit un accès lié avec tie à la bibliothèque db(3) (Berkeley DB, version 1.x).

GDBM_File

Fournit un accès lié avec tie à la bibliothèque gdbm(3).

NDBM_File

Fournit un accès lié avec tie à la bibliothèque ndbm(3).

SDBM_File

Fournit un accès lié avec tie aux fichiers sdbm(3) (simple DBM).

32-1-k. Interfaces utilisateurs

Ces modules fournissent une API décente pour les entrées/sorties de l'interface en ligne de commande.

Module

Description

Term::Cap

Utilise la bibliothèque termcap(3).

Term::Complete

Réalise une complétion programmable par des commandes sur des listes de mots.

Term::Readline

Utilise l'un des nombreux paquetages readline.

32-1-l. Authentification, sécurité et encryptage

Ces modules fonctionnent avec les espaces mémoire protégés dans lesquels s'exécutent les programmes.

Module

Description

Opcode

Active ou désactive les lors codes d'opérations (opcodes) de la compilation de code Perl en vue d'une utilisation avec le module Safe.

ops

Restreint les opérations non sûres lors de la compilation.

Safe

Compile et exécute du code dans des compartiments restreints.

32-1-m. Langage Perl, extensions et mécanismes internes.

(À ne pas confondre avec les intentions et les mécanismes externes.)

Module

Description

attributes

Consulte ou positionne les attributs d'un sous-programme ou d'une variable.

attrs

Consulte ou positionne les attributs d'un sous-programme ou d'une variable (obsolète).

base

Établit l'héritage des classes de base à la compilation.

Data::Dumper

Sérialise des structures de données Perl.

DB

Accède à l'API expérimentale du débogueur Perl.

Devel::Dprof

Profile l'exécution d'un programme Perl.

Devel::Peek

Charge des outils de débogage de données pour les programmeurs XS.

diagnostics

Force des avertissements verbeux et élimine les duplications.

Dumpvalue

Affiche à l'écran des valeurs de données.

English

Utilise des noms de variables plus longs pour les variables internes avec une ponctuation.

Env

Accède aux variables d'environnement dans %ENV en tant que scalaires ordinaires.

Errno

Charge les définitions de errno.h de la bibliothèque C et lie la variable %! avec tie.

Fatal

Remplace les fonctions internes avec des versions levant des exceptions lors d'un échec.

fields

Lors de la compilation, déclare les données attributs d'une classe et vérifie les accès à ces données.

less

Demande moins de quelque chose de la part de Perl (non implémenté).

re

Altère le comportement par défaut des expressions régulières.

strict

Restreint les constructions bâclées.

subs

Prédéclare les noms de sous-programmes dans le paquetage courant.

vars

Prédéclare des variables globales (obsolète voir our au chapitre 29.

32-1-n. Classes commodes

Ces modules fournissent des classes de base et d'autres facilités.

Module

Description

Tie::Array

Fournit une classe de base pour les tableaux liés avec tie.

Tie::Handle

Fournit une classe de base pour les handles liés avec tie.

Tie::Hash

Fournit une classe de base pour les hachages liés avec tie.

Tie::RefHash

Fournit des références comme clefs de hachage.

Tie::Scalar

Fournit une classe de base pour les scalaires liés avec tie.

Tie::SubstrHash

Fournit une interface similaire aux hachages pour une table de taille fixe avec des clefs de longueur fixe.

UNIVERSAL

Fournit une classe de base pour toutes les classes (références consacrées).

32-1-o. Avertissements et exceptions

Que faire lorsque les choses se passent mal.

Module

Description

Carp

Fournit des routines qui font des warn et des die avec la perspective de l'appelant.

warnings

Contrôle les avertissements à l'intérieur de la portée lexicale.

32-1-p. Support de documentation

Il existe une quantité de documentation à supporter.

Module

Description

Pod::Checker

Vérifie les erreurs de syntaxes des documents pod (utilisé par podchecker(1)) .

Pod::Functions

Liste les fonctions internes par type.

Pod::Html

Convertit les fichiers pod en HTML (utilisé par pod2html(1)).

Pod::InputObjects

Gère le support de documentation.

Pod::Man

Convertit du pod en format troff(1) pour le système man(1) (utilisé par pod2man(1)).

Pod::Parser

Fournit une classe de base pour créer des filtres et des traducteurs de pod.

Pod::Select

Extrait des sections de pod depuis l'entrée (utilisé par podselect(1)).

Pod::Text

Convertit des données pod en texte formaté en ASCII (utilisé par pod2text(1)).

Pod::Text::Color

Convertit des données pod en texte formaté en ASCII avec les séquences d'échappement ANSI pour les couleurs.

Pod::Text::Termcap

Convertit des données pod en texte ASCII avec les séquences d'échappement spécifiques du terminal.

Pod::Usage

Affiche un message d'utilisation dérivé de la documentation pod incluse dans le source.

32-1-q. Support d'installation de module

Ces modules aident d'autres modules à sauter à travers différents cerceaux.

Module

Description

AutoLoader

Charge des sous-programmes à la demande.

AutoSplit

Éclate un paquetage pour l'autochargement.

autouse

Diffère le chargement d'un module jusqu'à ce qu'une fonction de ce module soit utilisée.

blib

Utilise la bibliothèque depuis la version non installée d'une extension par Makemaker.

Config

Accède aux informations de configuration de Perl.

CPAN

Interroge, rapatrie et construit des modules Perl depuis des sites CPAN.

Devel::SelfStubber

Génère des souches (N.d.T. : stubs) pour un module en utilisant le module SelfLoader.

DynaLoader

Charge dynamiquement des bibliothèques C ou C++ en tant qu'extensions Perl.

Exporter

Implémente une méthode d'importation par défaut pour les modules traditionnels.

ExtUtils::Command

Fournit des utilitaires pour remplacer les commandes externes populaires dans un Makefile.

ExtUtils::Embed

Fournit des utilitaires pour inclure du Perl dans des programmes C ou C++.

ExtUtils::Install

Installe des fichiers dans la bibliothèque Perl du système.

ExtUtils::Installed

Gère l'inventaire des modules installés.

ExtUtils::Liblist

Détermine quelles bibliothèques utiliser et comment les utiliser.

ExtUtils::MakeMaker

Crée un Makefile pour une extension Perl.

ExtUtils::Manifest

Charge des outils pour écrire et vérifier un fichier MANIFEST.

ExtUtils::Miniperl

Écrit du code C pour perlmain.c.

ExtUtils::Mkbootstrap

Crée un fichier d'amorçage (bootstrap) pour être utilisé par DynaLoader.

ExtUtils::Mksymlists

Écrit des fichiers d'options de l'éditeur de liens pour les extensions dynamiques.

ExtUtils::MM_Cygwin

Supplante les méthodes se comportant à la manière d'Unix dans ExtUtils::MakeMaker.

ExtUtils::MM_OS2

Supplante les méthodes se comportant à la manière d'Unix dans ExtUtils::MakeMaker.

ExtUtils::MM_Unix

Fournit des méthodes utilisées par ExtUtils::MakeMaker.

ExtUtils::MM_VMS

Supplante les méthodes se comportant à la manière d'Unix dans ExtUtils::MakeMaker.

ExtUtils::MM_Win32

Supplante les méthodes se comportant à la manière d'Unix dans ExtUtils::MakeMaker.

ExtUtils::Packlist

Gère les fichiers .packlist.

ExtUtils::testlib

Ajoute des répertoires blib/* à @INC.

FindBin

Localise le répertoire d'installation pour le programme Perl en train de tourner.

lib

Manipule @INC lors de la compilation.

SelfLoader

Charge des fonctions uniquement à la demande.

XSLoader

Charge dynamiquement des bibliothèques C ou C++ en tant qu'extensions Perl.

32-1-r. Support de développement

Ces modules s'occupent des mesures de temps et des tests, pour voir dans quelles proportions votre code ne tourne ni plus rapidement ni plus proprement.

Module

Description

Benchmark

Compare les temps d'exécution de différentes versions de code.

Test

Utilise une infrastructure simple pour écrire des scripts de test.

Test::Harness

Lance des scripts de test standards avec des statistiques.

32-1-s. Compilateur Perl et générateur de code

Ces modules supportent des générateurs de code vers des sorties (N.d.T. : backends) diverses et variées pour Perl.

Module

Description

B

Charge des générateurs de code Perl (alias le « compilateur Perl »).

B::Asmdata

Fournit une donnée autogénérée sur les opérations atomiques Perl pour produire du bytecode.

B::Assembler

Assemble du bytecode Perl.

B::Bblock

Parcours les blocs basiques dans l'arbre syntaxique.

B::Bytecode

Utilise la sortie en bytecode du compilateur Perl.

B::C

Utilise la sortie de traduction en C du compilateur Perl.

B::CC

Utilise la sortie traduction optimisée en C du compilateur Perl.

B::Debug

Parcours l'arbre syntaxique Perl en affichant les infos de débogage à propos des opérations atomiques.

B::Deparse

Utilise la sortie du compilateur Perl pour reproduire du code Perl.

B::Disassembler

Désassemble du bytecode Perl.

B::Lint

Décèle les constructions douteuses.

B::Showlex

Montre les variables lexicales utilisées dans des fonctions ou des fichiers.

B::Stash

Montre quelles tables de symboles sont chargées.

B::Terse

Parcours l'arbre syntaxique Perl en affichant des infos laconiques à propos des opérations atomiques.

B::Xref

Génère des rapports avec des références croisées pour les programmes Perl.

ByteLoader

Charge du code Perl compilé en bytecode.

O

Fournit une interface générique aux sorties (backends) du compilateur Perl.

32-1-t. Modules relatifs à Microsoft

Si vous possédez la distribution Perl pour les systèmes Microsoft provenant d'ActiveState, les modules suivants, qui sont uniquement pour Microsoft, sont d'ores et déjà inclus pour vous. Si vous avez juste été chercher les sources de la distribution standard (en voulant peut-être la compiler avec l'émulateur d'environnement Unix de Cygwin), mais que vous tournez sur Wintel, vous pouvez obtenir tous ces modules depuis CPAN.

Module

Description

Win32::ChangeNotify

Surveille les événements relatifs aux fichiers et aux répertoires.

Win32::Console

Utilise la console Win32 et les fonctions du mode caractère.

Win32::Event

Utilise les objets événements Win32 depuis Perl.

Win32::EventLog

Traite les journaux d'événements Win32 depuis Perl.

Win32::File

Gère les attributs de fichier en Perl.

Win32::FileSecurity

Gère les FileSecurity Discretion Access Control Lists (Listes de contrôle d'accès discret aux fichiers sécurisés) en Perl.

Win32::IPC

Charge la classe de base pour les objets de synchronisation Win32.

Win32::Internet

Accède aux fonctions de WININET.DLL.

Win32::Mutex

Utilise les objets mutex Win32 en Perl.

Win32::NetAdmin

Gère les groupes et utilisateurs réseau en Perl.

Win32::NetResource

Gère les ressources réseau en Perl.

Win32::ODBC

Utilise les extensions ODBC pour Win32.

Win32::OLE

Utilise les extensions d'automatisation OLE.

Win32::OLE::Const

Extrait les définitions de constantes depuis TypeLib.

Win32::OLE::Enum

Utilise OLE Automation Collection Objects (objets collections d'automatisation OLE).

Win32::OLE::NLS

Utilise OLE National Langage Support (support de langages nationaux OLE).

Win32::OLE::Variant

Crée et modifie les variables OLE VARIANT.

Win32::PerfLib

Accède au compteur de performance de Windows NT.

Win32::Process

Crée et manipule des processus.

Win32::Semaphore

Utilise les objets sémaphores Win32.

Win32::Service

Gère les services du système.

Win32::Sound

Joue avec les sons Windows.

Win32::TieRegistry

Trifouille la base de registres

Win32API::File

Accède aux appels bas niveau de l'API système Win32 pour les fichiers et les répertoires.

Win32API::Net

Gère les comptes LanManager de Windows NT.

Win32API::Registry

Accède aux appels bas niveau de l'API système Win32 depuis WINREG.H.

32-2. Benchmark

 
Sélectionnez
use Benchmark qw(timethese cmpthese timeit countit timestr);

# Vous pouvez toujours passer du code sous forme de chaînes :
timethese $compteur, {
    'Nom1' => '...code1...',
    'Nom2' => '...code2...',
};

# Ou sous forme de références à des sous-programmes :
timethese $compteur, {
    'Nom1' => sub { ...code1... },
    'Nom2' => sub { ...code2... },
};

cmpthese $compteur, {
    'Nom1' => '...code1...',
    'Nom2' => '...code2...',
};

$t = timeit $compteur, ' code';
print "$compteur boucles de code ont pris : ", timestr($t), "\n";

$t = countit $temps, ' code';
$compteur = $t->iters;
print "$compteur boucles de code ont pris : ", timestr($t), "\n";

Le module Benchmark peut vous aider à déterminer lequel parmi plusieurs choix possibles s'exécute le plus rapidement. La fonction timethese lance les segments de codes spécifiés le nombre de fois demandé et rapporte combien de temps a pris chaque segment. Vous pouvez obtenir un joli diagramme trié si vous appelez cmpthese de la même façon.

Les segments de codes peuvent être passés sous forme de références de fonctions au lieu de chaînes (en fait, il faut que ce soit des références de fonctions si vous utilisez des variables lexicales provenant de la portée de l'appelant), mais la surcharge engendrée par l'appel peut influencer les mesures de temps. Si vous ne demandez pas assez d'itérations pour avoir une bonne mesure, la fonction émet un avertissement.

Des interfaces de bas niveau sont disponibles pour lancer un seul morceau de code soit un certain nombre de fois (timeit), soit un certain nombre de secondes (countit). Ces fonctions renvoient des objets Benchmark (voir une description dans la documentation en ligne). Avec countit, vous savez que cela a tourné pendant assez longtemps pour éviter les avertissements, car vous aviez spécifié un temps d'exécution minimum.

Pour tirer le meilleur profit du module Benchmark, vous aurez besoin d'un peu d'entraînement. En général, il n'est pas suffisant de lancer deux ou trois algorithmes sur le même jeu de données, car les mesures de temps ne reflètent que la manière dont ces algorithmes se sont bien comportés sur ce jeu de données précis. Pour obtenir une meilleure impression sur le cas général, vous aurez besoin de lancer plusieurs ensembles de benchmarks en faisant varier les jeux de données utilisés.

Par exemple, imaginez que vous vouliez savoir le meilleur moyen d'obtenir la copie d'une chaîne sans ses deux derniers caractères. Vous pensez à quatre façons de faire cela (il y en a d'autres bien sûr) : chop deux fois, copier et substituer, ou utiliser substr soit sur la partie gauche, soit sur la partie droite d'un assignement. Vous testez ces algorithmes sur des chaînes de longueur 2, 200 et 20_000 :

 
Sélectionnez
use Benchmark qw/countit cmpthese/;
sub lancer($) { countit(5, @_) }
for $taille (2, 200, 20_000) {
    $c = "." x $taille;
    print "\nTAILLE_DONNEES = $taille\n";
    cmpthese {
        chop2 => lancer q{
            $t = $c; chop $t; chop $t;
        },
        subs => lancer q{
            ($t = $c) =~ s/..\Z//s;
        },
        substr_g => lancer q{
            $t = $c; substr($t, -2) = ";
        },
        substr_d => lancer q{
            $t = substr($c, 0, length($c) -2);
        },
    };
}

ce qui affiche :

 
Sélectionnez
TAILLE_DONNEES = 2
             Rate substr_g     subs    chop2 substr_d
substr_g 579109/s       --      -2%     -36%     -37%
subs     593574/s       2%       --     -34%     -36%
chop2    903371/s      56%      52%       --      -2%
substr_d 920343/s      59%      55%       2%       --

TAILLE_DONNEES = 200
             Rate     subs substr_g substr_d    chop2
subs     561402/s       --      -2%      -8%     -24%
substr_g 574852/s       2%       --      -6%     -22%
substr_d 610907/s       9%       6%       --     -17%
chop2    737478/s      31%      28%      20%       --

TAILLE_DONNEES = 20000
            Rate  substr_d     subs substr_g    chop2
substr_d 35885/s        --     -45%     -45%     -46%
subs     65113/s       81%       --      -1%      -3%
substr_g 65472/s       82%       1%       --      -2%
chop2    66837/s       86%       3%       2%      --

Avec de petits jeux de données, l'algorithme « substr_d » tourne 2 % plus rapidement que l'algorithme « chop2 », mais sur de grands jeux de données, il tourne 46 % plus lentement.

Sur des jeux de données vides (aucun de montré ici), le mécanisme de substitution est le plus rapide. Il n'y a donc pas de solution meilleure que les autres dans tous les cas possibles et même ces mesures ne racontent pas toute l'histoire, puisque vous êtes toujours à la merci de votre système d'exploitation et de la bibliothèque C avec laquelle Perl a été compilé. Ce qui est bon pour vous peut devenir mauvais pour quelqu'un d'autre. Cela prend un certain temps pour être adroit avec les benchmarks. Entretemps, cela facilite les choses d'être un bon menteur.

32-3. Carp

 
Sélectionnez
use Carp;
croak "Nous en sommes là !";

use Carp qw(:DEFAULT cluck);
cluck "Voilà comment nous sommes arrivés là !";

Le module Carp vous permet d'écrire des modules dont les fonctions rapportent les erreurs de la même façon que les opérateurs internes du point de vue de l'utilisateur du module. Le module Carp fournit des routines que vous utilisez pratiquement comme les fonctions internes standard warn et die, mais qui changent le nom de fichier et le numéro de ligne de façon à ce que l'erreur ait l'air de provenir du code utilisateur plutôt que de votre code. En bref, Carp est un moyen formidable de renvoyer la faute sur quelqu'un d'autre que soi.

Il existe en fait quatre fonctions. La fonction carp marche comme l'opérateur warn,mais avec les informations sur le nom de fichier et le numéro de ligne relatives à l'appelant. La fonction croak marche comme die en levant une exception, mais en donnant là encore des informations relatives à l'appelant. Si vous préférez une longue complainte, utilisez cluck et confess au lieu de carp et croak respectivement, et vous obtiendrez une trace complète de la pile rapportant qui a appelé qui et armé de quels arguments (sans aucun doute le colonel Moutarde, dans la bibliothèque avec une clef anglaise). Vous devez importer cluck explicitement, car il n'est pas exporté normalement. Les gens ne veulent pas en général des traces complètes de la pile pour de simples avertissements, pour une raison ou pour une autre.

32-4. CGI

 
Sélectionnez
use CGI qw(:standard);
$qui = param("Nom");

$tel = param("Telephone");
@choix = param("Choix");

Le module CGI vous aide à gérer des formulaires HTML, spécialement les formulaires en plusieurs étapes où il est critique de passer d'une étape à une autre. L'exemple extrêmement simple ci-dessus s'attend à traiter un formulaire avec deux paramètres prenant des valeurs scalaires, comme des champs de texte ou des boutons radio et un autre prenant une valeur multiple, comme des listes déroulantes spécifiées avec « MULTIPLE ». Le module est encore plus sympathique que cela à plusieurs niveaux, en supportant des fonctionnalités comme le traitement des cookies, les valeurs persistantes pour les caddies multiécrans et la génération automatique de listes HTML et de tables que vous pouvez extraire d'une base de données pour n'en citer que quelques-unes. Le support de l'exécution à grande vitesse de scripts Perl précompilés via les services de mod_perl d'Apache est également fourni. Le livre de chez O'Reilly & Associates Writing Apache Modules with Perl and C, de Lincoln Stein et Doug MacEachern, vous dira tout sur ce sujet.

32-5. CGI::Carp

 
Sélectionnez
use CGI::Carp;
warn "Celle-ci est une complainte"; # Estampille avec le nom du
                                    # programme et la date
die "Mais celle-là est sérieuse";   #, Mais ne cause pas d'erreur
                                    # serveur 500

use CGI::Carp qw(carpout);          # Importe cette fonction
open(LOG, "> >/var/tmp/mon_cgi-log"
    or die "Impossible d'ajouter à mon_cgi-log : $!\n";
carpout(*LOG);                      # Utilise maintenant le journal
                                    # d'erreurs spécifiques au programme

use CGI::Carp qw(fatalsToBrowser);
die "Les messages d'erreurs fatales sont maintenant envoyés aussi au navigateur";

Le module CGI::Carp fournit des versions des fonctions internes Perl warn et die, plus les fonctions carp, cluck, confess et croak du module Carp qui sont plus parlantes et plus sûres également. Elles sont plus parlantes, car chaque message inclut la date et l'heure avec le nom du programme qui a émis les messages, ce qui est une aide précieuse lorsque vous utilisez un fichier journal partagé par une centaine de programmes différents qui le polluent tous en même temps avec un millier de messages différents.

Le module est également agréable pour les surfeurs du Web, puisque la mort prématurée d'un script CGI a tendance à causer des erreurs absconses « Server 500 » lorsque l'en-tête HTTP correct ne part pas du serveur avant que votre programme ne trépasse, et ce module s'assure que cela ne se produit pas. La fonction carpout redirige tous les avertissements et toutes les erreurs vers le handle de fichier spécifié. La directive fatalsToBrowser envoie également une copie de tels messages au navigateur de l'utilisateur. Ces services facilitent le débogage des problèmes dans les scripts CGI.

32-6. Class::Struct

 
Sélectionnez
use Class::Struct;
struct Chef => {        # Crée un constructeur Chef->new().
    nom => '$',         # La méthode nom() accède maintenant à une
                        # valeur scalaire.
    salaire => '$',     # Ainsi que salaire().
    debut => '$',       # Ainsi que debut().
};
struct Boutique => {    # Crée un constructeur Boutique->new().
    proprio => '$',     # La méthode proprio() accède maintenant à
                        # un scalaire.
    adrs => '@',        # Et la méthode adresse() accède à un tableau.
    stock => '%',       # Et la méthode stock() accède à un hachage.
    patron => 'Chef'    # Initialise avec Chef->new().
};

$magasin = Boutique->new();
$magasin->proprio('Abdul Alhazred');
$magasin->adrs(0, 'Miskatonic University');
$magasin->adrs(1, 'Innsmouth, Mass.');
$magasin->stock("livres", 208);
$magasin->stock("charmes", 3);
$magasin->stock("potions", "aucune");
$magasin->patron->nom('Dr. L. P. Hache');
$magasin->patron->salaire('folie');
$magasin->patron->debut(scalar localtime)

Le module Class:Struct fournit un moyen de « déclarer » une classe ayant des objets dont les champs sont d'un certain type. La fonction qui fait cela est appelée struct. Comme les structures d'enregistrements ne sont pas des types de base en Perl, chaque fois que vous désirez créer une classe pour fournir un objet ressemblant à une donnée d'enregistrement, vous devez définir une méthode constructeur ainsi que des méthodes accesseurs pour chaque donnée de champ, quelquefois appelées méthodes « wrapper ». La fonction struct du module Class::Struct vous soulage de cette tâche en créant une classe à la volée. Vous n'avez qu'à lui communiquer qu'elles doivent être les données membres, ainsi que leur type. La fonction crée une méthode constructeur appelée new dans le paquetage spécifié par le premier argument, plus une méthode accesseur d'attribut pour chaque membre, comme spécifié par le second argument, qui doit être une référence de hachage.

Les types de champ sont spécifiés, soit en tant que types internes en utilisant les symboles habituels « $ », « @ », « % » et « & », soit en tant qu'une autre classe en employant le nom de la classe. Le type de chaque champ sera forcé lorsque vous essayerez de modifier la valeur.

Beaucoup de modules standards utilisent Class:Struct pour créer leurs objets et accesseurs, y compris Net::hostent et User::pwent, dont vous pouvez regardez les sources et vous en servir comme modèles. Voir également les modules CPAN Tie::SecureHash et Class::Multimethods pour des approches plus élaborées de l'autogénération de classes et de méthodes accesseurs. Voir la section Gestion des données d'instance au chapitre 12, Objets.

32-7. Config

 
Sélectionnez
use Config;
if ($Config{cc} =~ /gcc/) {
    print "Ce perl a été compilé avec GNU C.\n";
}
use Config qw(myconfig config_sh config_vars);
print myconfig();           # comme perl -V sans aucun motif
print config_sh();          # donne absolument tout

config_vars qw/osname osvers archname/;

Le mécanisme de configuration utilisé pour compiler et installer Perl rassemble une profusion d'informations sur votre système. Le module Config exporte par défaut une variable de hachage liée avec tie, nommée %Config, qui donne accès à environ 900 valeurs de configuration différentes. (Ces valeurs sont également accessibles à travers l'option -V:MOTIF de la ligne de commande de Perl.) Config fournit également trois fonctions qui donnent un accès à ces valeurs dans le style du shell, comme montré ci-dessus. Par exemple, le dernier appel pourrait afficher :

 
Sélectionnez
osname='linux';
osvers='2.4.2';
archname='i386-linux';

La documentation en ligne du module décrit les variables de configuration et leurs valeurs possibles. Prenez garde si vous déplacez votre exécutable perl vers un système autre que celui sur lequel il a été compilé, ces valeurs peuvent ne pas refléter la réalité actuelle ; par exemple, si vous faites tourner un binaire Linux ou Solaris sur un système BSD.

32-8. CPAN

 
Sélectionnez
# Obtient un shell CPAN interactif.
%perl -MCPAN -e shell

# S'enquiert juste des recommandations de mise à niveau.
% perl -MCPAN -e 'CPAN::Shell->r'

# Installe le module indiqué en mode batch.
% perl -MCPAN -e "install Class::Multimethods"

Le module CPAN est une interface automatisée et conviviale au Comprehensive Perl Archive Network, décrit au chapitre 22, CPAN. Au contraire de la plupart des modules que vous pouvez rencontrer, il est destiné à être invoqué depuis la ligne de commande, exactement comme un petit programme. La première fois que vous l'appelez, le module vous demande le site miroir CPAN par défaut et d'autres renseignements dont il a besoin. Après cela, vous pouvez lancer son shell interactif pour faire des requêtes et sélectionner des modules à installer, demander au module des recommandations sur les modules devant être remis à niveau ou simplement lui faire installer un module particulier.

32-9. Cwd

 
Sélectionnez
use Cwd;
$rep = getcwd(); # Où suis-je ?

use Cwd 'chdir';
chdir "/tmp"; # Met à jour $ENV{PWD}.

use Cwd 'realpath';
print realpath("/usr////spool//mqueue/../"); # affiche /var/spool

Le module Cwd fournit des fonctions indépendantes de la plate-forme pour déterminer le répertoire de travail courant de votre processus. C'est mieux que de lancer un shell exécutant pwd(1), car les systèmes non conformes à POSIX ne garantissent pas qu'ils connaissent une telle commande et Perl ne se limite pas uniquement à tourner sur les plates-formes POSIX. La fonction getcwd, laquelle est exportée par défaut, renvoie le répertoire de travail courant en utilisant le mécanisme réputé pour être le plus sûr sur la plate-forme courante. Si vous importez la fonction chdir, elle supplante l'opérateur interne avec celui du module, lequel met à jour la variable d'environnement $ENV{PWD} ; les commandes que vous pourriez lancer ensuite et qui tiendraient compte de cette variable auraient alors une vision cohérente de leur univers. La fonction realpath résout dans son argument représentant un nom de chemin tous les liens symboliques et tous les composants de chemin relatif afin de renvoyer un chemin complet de répertoire sous une forme canonique, exactement comme realpath(3).

32-10. Data::Dumper

 
Sélectionnez
use Data::Dumper;
print Dumper($magasin);

Lorsqu'on l'utilise sur l'exemple tiré de la définition de Class::Struct, ceci affiche :

 
Sélectionnez
$VAR1 = bless( {
    'Boutique::patron' => bless( {
                                     'Chef::salaire' => 'folie',
                                     'Chef::nom'     => 'Dr. L. P. Hache',
                                     'Chef::debut'   => 'Fri Apr 13 19:33:04 2001'
                                 }, 'Chef' ),
    'Boutique::stock' => {
                             'livres'  => 208,
                             'charmes' => 3,
                             'potions' => 'aucune'
                         },
    'Boutique::proprio' => 'Abdul Alhazred',
    'Boutique::adrs' => [
                            'Miskatonic University',
                            'Innsmouth, Mass.'
                        ]
    }, 'Boutique' );

La fonction Dumper du module Data::Dumper prend une liste de scalaires (incluant des références, qui peuvent même se référer à des objets) et renvoie une chaîne affichable ou evaluable qui reproduit précisément une copie fidèle de l'original. Vous pouvez utiliser ceci pour écrire une version de sauvegarde d'une structure de donnée dans un fichier ordinaire sur disque ou dans un fichier DBM, ou encore la passer à un autre processus via un pipe ou une connexion socket. Ce module peut être utilisé avec les modules MLDBM de CPAN et DB_File pour implémenter un fichier DBM à même de stocker de manière transparente des valeurs de données complexes, et non seulement des chaînes à plat. D'autres modules de transformation en chaînes (stringification) (ou sérialisation, ou formatage de présentation, marshalling) incluent Storable et FreezeThaw, tous deux disponibles depuis CPAN.

32-11. DB_File

 
Sélectionnez
use DB_File;

Lie avec tie un hachage à un fichier dans le style de DBM :

 
Sélectionnez
tie(%hachage, "DB_File", $fichier)  # Ouvre une base de données.
    or die "Impossible d'ouvrir $fichier : $!";

$v = $hachage{"clef"};              # Extrait depuis la base de données.
$hachage{"clef"} = "valeur";        # Positionne une valeur dans la base.
untie %hachage;

Lie avec tie un hachage à un fichier B-tree (arbre balancé ou équilibré), mais continue d'y accéder en tant que hachage DBM ordinaire :

 
Sélectionnez
tie(%hachage, "DB_File", "mon_arbre", O_RDWR|O_CREAT, 0666, $DB_BTREE)
    or die "Impossible d'ouvrir le fichier 'mon_arbre' : $!";

while (($c, $v) = each %hachage) {      # Parcourt dans l'ordre
    print "$c => $v\n";
}

Lie avec tie un tableau à un fichier texte brut :

 
Sélectionnez
tie(@lignes, "DB_File", $fic_texte, O_RDWR|O_CREAT, 0666, $DB_NUM_ENREG)
    or die "Impossible d'ouvrir le fichier texte $fic_texte : $!";

# Écrit quelques lignes dans le fichier, en écrasant les anciennes.
$lignes[0] = "première ligne";
$lignes[1] = "deuxième ligne";
$lignes[2] = "troisième ligne";

push @lignes, "pénultième", "dernière"; # Met deux lignes à la fin
                                        # du fichier
$wc = scalar @lignes;                   # Compte le nombre de lignes
$derniere = pop @lignes;                # Supprime et extrait la dernière
                                        # ligne

Le module DB_File donne un accès lié avec tie à une DB Berkeley.(226) La fonction tie vous donne par défaut une base de données standard dans le style de DBM, avec certaines fonctionnalités que l'on ne retrouve dans aucune bibliothèque DBM : il n'existe pas de limites de taille ni pour les clefs ni pour les valeurs et vos données sont stockées dans un format indépendant de l'ordre des octets.

Le deuxième mécanisme de tie utilise des B-trees (arbres balancés ou équilibrés) pour vous donner un véritable fichier ISAM (Indexed Sequential Access Method, méthode d'accès séquentiel indexé), c'est-à-dire un hachage dont les clefs sont automatiquement triées dans l'ordre alphabétique par défaut, mais configurable par l'utilisateur.

Le troisième mécanisme de tie lie un tableau à un fichier d'enregistrements (des lignes de texte par défaut) de façon à ce que les modifications dans le tableau se répercutent automatiquement sur le disque. Ceci simule un accès aléatoire par numéro de ligne dans un fichier texte ordinaire. L'interface standard est conforme à la version 1.x de Berkeley DB ; si vous souhaitez employer les nouvelles fonctionnalités disponibles dans Berkeley 2.x ou 3.x, utilisez plutôt le module BerkeleyDB de CPAN.

À partir de la version 2.x, Berkeley DB supporte intrinsèquement le verrouillage, ce qui n'était pas le cas dans les versions précédentes. Voir la section Verrouillage de fichier du chapitre 16 pour une description de la manière sûre dont vous pouvez verrouillez n'importe quel type de fichier de base de données en utilisant flock sur un fichier sémaphore.

32-12. Dumpvalue

 
Sélectionnez
use Dumpvalue;

Dumpvalue->new->dumpValue($magasin);

Lorsqu'on l'utilise sur l'exemple tiré de la définition de Class::Struct, ceci affiche :

 
Sélectionnez
'Boutique::adrs' => ARRAY(0x816d548)
    0 'Miskatonic University'
    1 'Innsmouth, Mass.'
'Boutique::patron' => Chef=HASH(0x80f1538)
    'Chef::debut' => 'Fri Apr 13 19:33:04 2001'
    'Chef::nom' => 'Dr. L. P. Hache'
    'Chef::salaire' => 'folie'
'Boutique::proprio' => 'Abdul Alhazred'
'Boutique::stock' => HASH(0x81976d0)
    'charmes' => 3
    'livres' => 208
    'potions' => 'aucune'

Il s'agit d'un autre module facilitant l'affichage de données complexes. Il n'est pas tant destiné au formatage de présentation (marshalling) qu'à un affichage agréable. Il est utilisé par la commande x du débogueur Perl. En tant que tel, il offre une quantité impressionnante d'options pour contrôler le format de sortie. Il donne également accès aux tables de symboles de paquetages de Perl pour vider le contenu d'un paquetage entier.

32-13. English

 
Sélectionnez
use English;

# Utilise des noms dans le style de awk
$RS = ''; # au lieu de $/
while (<>) {
    next id $NR < 10; # au lieu de $.
    ...
}

# Idem, mais encore plus long à la Cobol
$INPUT_RECORD_SEPARATOR = ";
while (<>) {
    next if $INPUT_LINE_NUMBER < 10;
    ...
}

Le module English fournit des alias encombrants pour les variables internes à destination des prodigieux dactylos qui ont une haine viscérale des identificateurs non-alphabétiques (et un amour viscéral pour la touche Blocage Majuscules, ou Caps Lock). Comme avec toutes les importations, ces alias ne sont disponibles que dans le paquetage courant. Les variables sont toujours accessibles sous leur véritable nom. Par exemple, un fois que vous avez fait un use de ce module, vous pouvez utiliser $PID si $$ vous dérange ou $PROGRAM_NAME si $0 vous donne mal au cœur. Certaines variables ont plus d'un alias. Voir le chapitre 28, Noms spéciaux pour une description complète de toutes les variables internes et de leur alias en anglais tirés du module English.

32-14. Errno

 
Sélectionnez
use Errno;
unless (open(HF, $chemin)) {
    if ($!{ENOENT}) { # Nous n'avons pas besoin d'importer ceci !
    warn "$chemin n'existe pas\n";
    else {
        warn "Échec de l'ouverture de $chemin : $!";
    }
}

use Errno qw(EINTR EIO :POSIX)
if ($! == ENOENT) { ... }

Le module Errno rend accessibles les noms symboliques pour l'ensemble des valeurs de statut d'erreur lorsqu'un appel système échoue, mais il ne les exporte pas toutes par défaut. Le module n'a qu'un seul tag d'exportation, « :POSIX », qui n'exporte que les symboles définis dans le standard POSIX 1003.1. Le module rend également magique la variable globale %! en utilisant tie. Vous pouvez indicer le hachage %! en employant n'importe quelle valeur valide d'errno sur votre système, pas seulement les valeurs POSIX, et sa valeur n'est vraie que s'il s'agit de l'erreur actuelle.

32-15. Exporter

Dans votre fichier Mon_Module.pm :

 
Sélectionnez
package Mon_Module;

use strict;
use Exporter;

our $VERSION = 1.00;        # Ou supérieure...
our @ISA = qw(Exporter);

our @EXPORT = qw(f1 %h);    # Symboles importés par défaut.
our @EXPORT_OK = qw(f2 f3); # Symboles importés seulement sur demande.
our %EXPORT_TAGS = (        # Mappage pour :raccourcis.
    a => [qw(f1 f2 f3)],
    b => [qw(f2 %h)],
);

# Votre code ici.

1;

Depuis un programme ou un autre module qui fait un use du vôtre :

 
Sélectionnez
use Mon_Module;                  # Importe tout ce qu'il a dans @Export.
use Mon_Module ();               # Charge le module sans rien importer.
use Mon_Module "f1", "f2", "%h"; # Deux fonctions et une variable.
use Mon_Module qw(:DEFAULT f3);  # Tout ce qu'il y a dans @Export +
                                 # une fonction.
use Mon_Module "f4";             # Erreur fatale, car f4 n'est pas exportée.

Dès que quelqu'un invoque une déclaration use pour charger votre module, il appelle la méthode import depuis votre module pour rapatrier tous les symboles dont il a besoin dans le paquetage de l'appelant. Votre module (celui qui fait les exportations) peut définir la méthode import comme il le souhaite, mais la manière standard est d'en hériter à partir du module de classe Exporter. C'est ce que fait le code ci-dessus.

Le module Exporter sert de classe de base pour les modules qui souhaitent établir leurs propres exportations. Curieusement, les modules orientés objet n'utilisent généralement pas Exporter, puisqu'ils n'exportent normalement rien (les appels de méthodes n'ont pas besoin d'être exportés). Toutefois, le module Exporter lui-même est accessible de manière orientée objet à cause du tableau @ISA que vous avez installé, comme dans notre exemple. Lorsqu'un autre programme ou qu'un autre module fait un use de votre module, vous utiliserez automatiquement la méthode Exporter::import par le biais de l'héritage.

Le tableau @EXPORT du module contient une liste de symboles (des fonctions et même des variables) que le code appelant importe automatiquement avec une instruction use sans rien d'autre. Le tableau @EXPORT_OK est composé des symboles qui peuvent être importés si on les demande nommément. Le numéro $VERSION est consulté si l'instruction use demande une version particulière (ou plus récente) du module. Beaucoup, beaucoup d'autres fonctionnalités sont disponibles. Voir le chapitre 11, Modules, ainsi que la page de man en ligne du module Exporter.

32-16. Fatal

Le module Fatal fait échouer les fonctions plus spectaculairement. Il remplace les fonctions qui normalement retournent faux en cas d'échec avec des sur-couches qui lèvent une exception si la véritable fonction renvoie faux. Ainsi, vous pouvez utiliser en toute sûreté ces fonctions sans tester explicitement leur valeur de retour à chaque appel.

Les fonctions définies par l'utilisateur et les fonctions internes peuvent toutes être enrobées, sauf les fonctions internes qui ne peuvent pas être exprimées par des prototypes. Une tentative de supplanter une fonction interne non enrobable lève une exception. Ceci inclut system, print, printf, exec, split, grep et map ou plus génériquement, toute FONC pour laquelle prototype "CORE::FONC" renvoie faux, y compris la fonction prototype elle-même.

Si le symbole :void apparaît dans la liste d'importation, les fonctions citées ensuite dans la liste se limitent à lever une exception lorsque la fonction est appelée dans un contexte void c'est-à-dire, lorsque la valeur renvoyée est ignorée. (Faites attention à la dernière instruction dans un sous-programme.) Par exemple :

 
Sélectionnez
use Fatal qw(:void open close);

# open proprement vérifié, aucune exception n'est donc levée en cas d'échec.
if (open(HF, "< /rien_de_tel") { warn "aucun /rien de tel : $!"; }

# close improprement vérifié, une exception est donc levée en cas d'échec.
close HF;

32-17. Fcntl

 
Sélectionnez
use Fcntl;              # Importe les constantes standard de fcntl.h.
use Fcntl ":flock";     # Importe les constantes LOCK_*.
use Fcntl ":seek";      # Importe SEEK_CUR, SEEK_SET et SEEK_END.
use Fcntl ":mode";      # Importe les constantes de test de stat S_*.
use Fcntl ":Fcompat";   # Importe les constantes F*.

Le module Fcntl fournit des constantes à employer avec diverses fonctions internes de Perl. L'ensemble importé par défaut inclut des constantes comme F_GETFL et F_SETFL pour fcntl, SEEK_SET et SEEK_END pour seek et sysseek et O_CREAT et O_EXCL pour sysopen. Les tags d'importation supportés incluent « :flock » pour accéder aux constantes LOCK_EX, LOCK_NB, LOCK_SH et LOCK_UN pour flock ; « :mode » pour aller chercher les constantes de sys/stat.h comme S_IRUSR et S_ISFIFO ; « :seek » pour obtenir les trois arguments de seek et sysseek ; et « :Fcompa t » pour avoir les symboles désuets commençant par un « F », mais pas par« F_ », comme FAPPEND, FASYNC et FNONBLOCK. Voir la documentation en ligne du module Fcntl et la documentation de votre système d'exploitation pour les appels systèmes concernés, comme fcntl(2), lseek(2), open(2) et stat(2).

32-18. File::Basename

 
Sélectionnez
use File::Basename;

$nom_complet = "/usr/local/src/perl-5.6.1.tar.gz";

$fichier = basename($nom_complet);
# fichier= "perl-5.6.1.tar.gz"

$rep = dirname($nom_complet);
rep="/usr/local/src"

($fichier,$rep,$ext) = fileparse($nom_complet, qr/\..*/);
# rep="/usr/local/src/" fichier="perl-5" ext=".6.1.tar.gz"

($fichier,$rep,$ext) = fileparse($nom_complet, qr/\.[^.]*/);
# rep="/usr/local/src/" fichier="perl-5.6.1.tar" ext=".gz"

($fichier,$rep,$ext) = fileparse($nom_complet, qr/\.\D.*/);
# rep="/usr/local/src/" fichier="perl-5.6.1" ext=".tar.gz"

($fichier,$rep,$bak) = fileparse("/tmp/fichier.bak",
                            qr/~+$/, qr/\.(bak|orig|save)/)
# rep="/tmp/" fichier="fichier" bak=".bak";

($fichier,$rep,$bak) = fileparse("/tmp/fichier~",
                            qr/~+$/, qr/\.(bak|orig|save)/)
# rep="/tmp/" fichier="fichier" bak="~";

Le module File::Basename fournit des fonctions pour décomposer les noms de chemin en leurs composants individuels. La fonction dirname sort la portion représentant le répertoire et basename la portion ne représentant pas le répertoire. La fonction plus élaborée fileparse distingue dans le nom du chemin complet, le nom du répertoire, le nom du fichier et le suffixe ; vous devez fournir une liste d'expressions régulières décrivant les suffixes qui vous intéressent. Les exemples ci-dessus illustrent comment le choix de motifs pour le suffixe affecte le résultat. Par défaut, ces fonctions analysent des noms de chemin selon les conventions natives de votre plate-forme. La fonction fileparse_set_fstype sélectionne les règles d'analyse pour une plate-forme différente, comme fileparse_set_fstype("VMS") pour analyser les noms utilisant les règles de VMS, même lorsque l'on tourne sur des systèmes non VMS.

32-19. File::Compare

 
Sélectionnez
use File::Compare;

printf "fichier_A et fichier_B sont %s.\n",
    compare("fichier_A","fichier_B") ? "différents" : "identiques";
    
use File::Compare 'cmp';
sub arranger($) {
    my $ligne = $_[0];
    for ($ligne) {
        s/\^s+//; # Coupe les espaces au début.
        s/\s+$//; # Coupe les espaces à la fin.
    }
    return uc($ligne);
}

if (not cmp("fichier_A", "fichier_B",
            sub {arranger $_[0] eq arranger $_[1]} ) {
    print "fichier_A et fichier_B sont à peu près pareils.\n";
}

Le module File::Compare fournit une fonction, compare, qui compare le contenu des deux fichiers qu'on lui passe. Elle renvoie 0 si les fichiers contiennent les mêmes données, 1 s'ils contiennent des données différentes et -1 si l'on a rencontré une erreur en accédant les fichiers cités. Si vous passez comme troisième argument une référence de sous-programme, cette fonction est appelée répétitivement pour déterminer si deux lignes sont équivalentes. Pour assurer la compatibilité avec le programme cmp(1), vous pouvez explicitement importer la fonction en tant que cmp. (Ceci n'affecte pas l'opérateur binaire cmp.)

32-20. File::Copy

 
Sélectionnez
use File::Copy;

copy("/tmp/fichier_A", "/tmp/fichier_A.orig") or die "copie échouée : $!";
copy("/etc/motd", *STDOUT) or die "copie échouée : $!";
move("/tmp/fichier_A", "/tmp/fichier_A.orig") or die "déplacement échoué : $!";

use File::Copy qw/cp mv/;       # Importe les noms Unix habituels.
cp("/tmp/fichier_A", "/tmp/fichier_A.orig") or die "copie échouée : $!";
mv("/tmp/fichier_A", "/tmp/fichier_A.orig") or die "déplacement échoué : $!";

Le module File::Copy exporte deux fonctions, copy et move, qui respectivement copie ou renomme leur premier argument vers leur second, de la même manière qu'un appel aux commandes Unix cp(1) et mv(1) (noms que vous pouvez utiliser si vous les importez explicitement). La fonction copy accepte également comme arguments des handles de fichiers. Ces fonctions renvoient vrai lorsqu'elles fonctionnent et faux lorsqu'elles échouent, en positionnant $! ($OS_ERROR) de manière appropriée. (Malheureusement, vous ne pouvez pas dire si quelque chose comme « Permission denied » s'applique au premier fichier ou au second.) Ces fonctions sont en quelque sorte un compromis entre le confort et la précision. Elles ne supportent pas les nombreuses options et optimisations de cp(1) et mv(1), comme la copie récursive, la copie de sauvegarde automatique, la conservation des dates et heures originales et des informations sur les propriétaires des fichiers, ou la confirmation interactive. Si vous avez besoin de ces fonctionnalités, il vaut certainement mieux appeler les versions de votre plate-forme pour ces commandes.(227) Gardez bien à l'esprit que tous les systèmes ne supportent pas les mêmes commandes ou n'emploient pas les mêmes options pour ces commandes.

 
Sélectionnez
system("cp -R -pi /tmp/rep1 /tmp/rep2") == 0
    or die "le statut de la commande externe cp est $?";

32-21. File::Find

 
Sélectionnez
use File::Find;

# Affiche tous les répertoires en dessous du répertoire courant.
find sub { print "$File::Find::name\n" if -d }, ".";

# Calcule l'espace total utilisé par les fichiers des répertoires listés.
@reps = @ARGV ? @ARGV : ('.');
my $tot = 0;
find sub { $tot += -s }, @reps;
print "@reps contiennent $tot octets\n";

# Modifie le comportement par défaut pour traverser les liens
# symboliques et visiter les sous-répertoires en premier
find { wanted => \&ma_fonction, follow => 1, bydepth=>1 }, ".";

La fonction find du module File::Find descend récursivement dans des répertoires. Son premier argument doit être une référence à une fonction et tous les arguments suivants doivent être des répertoires. La fonction est appelée pour chaque fichier des répertoires listés. À l'intérieur de cette fonction, la variable $_ est positionnée avec le nom de base du fichier actuellement visité et le répertoire de travail courant du processus est par défaut mis à ce répertoire. La variable de paquetage $File::Find::name est le nom de chemin complet du fichier visité. Une autre convention d'appel prend comme premier argument une référence à un hachage contenant des spécifications d'options, incluant « wanted », « bydepth », « follow », « follow_fast », « follow_skip », « no_chdir », « untaint », « untaint_pattern » et« untaint_skip », comme le détaille complètement la documentation en ligne. Ce module est également utilisé par le programme de conversion standard find2perl(1) qui vient avec la distribution Perl.

32-22. File::Glob

 
Sélectionnez
use File::Glob ':glob'; # Supplante le glob interne.
@liste = <*.[Cchy]>;    # Utilise maintenant le glob POSIX, pas le
                        # glob csh.

use File::Glob qw(:glob csh_glob);

@sources = bsd_glob("*.{C,c,h,y,pm,xs}", GLOB_CSH);
@sources = csh_glob("*.{C,c,h,y,pm,xs}"); # (idem)

use File::Glob ':glob';
# appelle glob avec des arguments supplémentaires
$rep_maison = bsd_glob('~hackerjr', GLOB_TILDE | GLOB_ERR);
if (GLOB_ERROR) {
    # Une erreur s'est produite en développant le répertoire maison
}

La fonction bsd_glob du module File::Glob implémente la routine glob(3) de la librairie C. Un second argument facultatif contient des options gouvernant des propriétés supplémentaires de correspondances. Le tag d'importation :glob importe à la fois la fonction et les options nécessaires.

Le module implémente également une fonction csh_glob. C'est elle que l'opérateur interne de Perl glob et l'opérateur de globalisation de fichiers GLOBPAT appellent réellement. Appeler csh_glob revient (en grande partie) à appeler bsd_glob de cette manière :

 
Sélectionnez
bsd_glob(@_ ? $_[0] : $_,
    GLOB_BRACE | GLOB_NOMAGIC | GLOB_QUOTE | GLOB_TILDE);

Si vous importez le tag :glob, tous les appels aux opérateurs internes de globalisation de fichiers dans le paquetage courant appelleront alors réellement la fonction du module bsd_glob à la place de la fonction csh_glob. Une raison pour laquelle vous voudriez faire cela, bien que bsd_glob s'occupe de motifs comprenant des espaces, est que csh_glob s'en occupe d'une manière, heu, historique. Les anciens scripts écriraient <*.c *.h> pour globaliser les deux motifs. De toute façon, aucune des fonctions n'est gênée par des espaces dans les véritables noms de fichiers.

La fonction bsd_glob prend un argument contenant le motif de globalisation de fichiers (et pas un motif d'expression régulière) plus un argument facultatif pour les options. Les noms de fichiers commençant par un point ne correspondent pas à moins de le demander spécifiquement. La valeur de retour est influencée par les options du second argument, qui doivent être des bits joints entre eux par des OU :(228)

GLOB_BRACE

  • Traite en amont la chaîne pour développer les chaînes {motif,motif,...} comme csh(1) le ferait. Le motif {} n'est pas développé pour des raisons historiques, surtout pour faciliter la saisie des motifs de find(1).

GLOB_CSH

  • Synonyme de GLOB_BRACE | GLOB_NOMAGIC | GLOB_QUOTE | GLOB_TILDE.

GLOB_ERR

  • Renvoie une erreur lorsque la fonction bsd_glob rencontre un répertoire qu'elle ne peut ouvrir ou lire. D'ordinaire, bsd_glob saute les erreurs pour rechercher d'autres correspondances.

GLOB_MARK

  • Ajoute un slash à la fin des répertoires.

GLOB_NOCASE

  • Par défaut, les noms de fichiers sont sensibles à la casse (majuscules/minuscules) ; cette option fait que bsd_glob ignore les différences de casse. (Mais voir ci-dessous les exceptions sur les systèmes à la MS-DOS).

GLOB_NOCHECK

  • Si le motif ne correspond à aucun nom de chemin, alors bsd_glob renvoie une liste uniquement constituée du motif, comme le fait /bin/sh. Si l'option GLOB_QUOTE est positionnée, les conséquences qu'elle entraîne sont présentes dans le motif renvoyé.

GLOB_NOMAGIC

  • Idem que, GLOB_NOCHECK mais le motif n'est renvoyé que s'il ne contient aucun des caractères spéciaux *, ? ou [. NOMAGIC est là pour simplifier l'implémentation du comportement historique de globalisation de csh(1) et ne devrait probablement pas être utilisé ailleurs.

GLOB_NOSORT

  • Par défaut, les noms de chemins sont triés dans un ordre croissant (en utilisant les comparaisons de caractères habituelles, sans respecter les valeurs des locales). Cette option évite ce tri avec comme résultat une légère amélioration de la vitesse.

GLOB_QUOTE

  • Utilise le caractère antislash \ pour les protections : chaque occurrence dans le motif d'un antislash suivi par un caractère est remplacée par ce caractère, évitant les interprétations spéciales du caractère en question. (Mais voir ci-dessous les exceptions sur les systèmes à la MS-DOS).

GLOB_TILDE

  • Autorise l'emploi de motifs dont le premier composant du chemin est ~UTILISATEUR. Si UTILISATEUR est omis, le tilde lui-même (ou suivi par un slash) représente le répertoire maison de l'utilisateur courant.

La fonction bsd_glob renvoie une liste (qui peut être vide) des chemins correspondants, cette liste pouvant devenir marquée si cela importe à votre programme. En cas d'erreur, GLOB_ERROR sera vrai et $! ($OS_ERROR) sera positionnée avec l'erreur système standard. Il est garanti que GLOB_ERROR sera faux s'il ne se passe aucune erreur, et de valoir soit GLOB_ABEND, sinon GLOB_NOSPACE.(GLOB_ABEND signifie que la fonction bsd_glob s'est arrêtée à cause d'une erreur et GLOB_NOSPACE à cause d'un manque de mémoire.) Si bsd_glob a déjà trouvé des chemins correspondant lorsque l'erreur se produit, elle renvoie la liste des noms de fichiers trouvés jusque là, mais positionne aussi GLOB_ERROR. Remarquez que cette implémentation de bsd_glob diffère de la plupart des autres en ce qu'elle ne considère pas ENOENT et ENOTDIR comme des conditions d'arrêt sur erreur. À la place, elle poursuit son traitement malgré ces erreurs, sauf si l'option GLOB_ERR est positionnée.

Si aucune option n'est donnée, les comportements par défaut de votre système sont respectés, c'est-à-dire que les noms de fichiers qui différent seulement par leur casse seront confondus sur VMS, OS/2, les vieux Mac OS (mais pas Mac OS X) et les systèmes Microsoft (mais pas lorsque Perl a été compilé avec Cygwin). Si vous ne donnez aucune option et que vous voulez toujours que ce comportement s'applique, vous devez alors inclure GLOB_NOCASE dans les options. Quel que soit le système sur lequel vous êtes, vous pouvez modifier votre comportement par défaut en important à l'avance les options :case ou :nocase.

Sur les systèmes à la MS-DOS, l'antislash est un caractère séparateur de répertoires valide.(229) Dans ce cas, l'emploi d'un antislash comme caractère de protection (via GLOB_QUOTE) interfère avec l'emploi de l'antislash en tant que séparateur de répertoires. La meilleure solution (la plus simple et la plus portable) est d'utiliser des slashs comme séparateurs de répertoires, des antislashs pour les protections. De toute façon, cela n'a rien à voir avec les attentes de certains utilisateurs, ainsi les antislashs (sous GLOB_QUOTE) ne protègent que les métacaractères de globalisation [, ], {, }, -, ~ et \ lui-même.Tous les autres antislashs sont passés inchangés, si vous parvenez à en avoir avec le propre mécanisme de Perl pour la protection par antislashs dans les chaînes. Cela peut prendre jusqu'à quatre antislashs pour finalement correspondre à un seul dans le système de fichier. Ceci est tellement complètement délirant que même les utilisateurs des systèmes à la MS-DOS devraient sérieusement penser à employer des slashs. Si vous voulez vraiment utiliser des antislashs, jetez un œil au module standard File::DosGlob qui est plus susceptible de correspondre à vos goûts que la globalisation de fichiers à la mode Unix.

32-23. File::Spec

 
Sélectionnez
use File::Spec; # style orienté objet

$chemin = File::Spec->catfile("sous_rep", "fichier");
    # 'sous_rep/fichier' sur Unix, OS2 ou Mac OS X
    # 'sous_rep:fichier' sur les (vieux) Macs d'Apple
    # 'sous_rep\fichier' sur Microsoft

$chemin = File::Spec->catfile("", "rep1", "rep2", "fichier");
    # '/rep1/rep2/fichier' sur Unix, OS2 ou Mac OS X
    # ':rep1:rep2:fichier' sur les (vieux) Macs d'Apple
    # '\rep1\rep2\fichier' sur Microsoft

use File::Spec::Unix;
$chemin = File::Spec->catfile("sous_rep", "fichier");
    # 'sous_rep/fichier' (même si exécuté sur des systèmes non-Unix)

use File::Spec::Mac;
$chemin = File::Spec->catfile("sous_rep", "fichier");
    # 'sous_rep:fichier'

use File::Spec::Win32;
$chemin = File::Spec->catfile("sous_rep", "fichier");
    # 'sous_rep\fichier'

# Utilise plutôt l'interface fonctionnelle.
use File::Spec::Functions;
$chemin = catfile("sous_rep", "fichier");

La famille de modules File::Spec vous permet de construire des chemins utilisant des répertoires et des noms de fichiers sans coder en dur les séparateurs de répertoires spécifiques aux plates-formes. Les systèmes supportés incluent Unix, VMS, Mac et Win32. Ces modules offrent tous une méthode de classe catfile qui concatène chaque composant de chemin en utilisant le séparateur de chemin spécifique à la plate-forme. Le module File::Spec renvoie des résultats différents selon votre plate-forme courante. Les autres renvoient des résultats spécifiques à la plate-forme en question. Le module File::Spec::Functions fournit une interface fonctionnelle.

32-24. File::stat

 
Sélectionnez
use File::stat;
$st = stat($fichier) or die "stat de $fichier impossible : $!";
if ($st->mode & 0111 and $st->nlink > 1) {
    print "$fichier est exécutable et possède plusieurs liens\n";
}

use File::stat ":FIELDS";
stat($fichier) or die "stat de $fichier impossible : $!";
if ($st_mode & 0111 and $st_nlink > 1) {
    print "$fichier est exécutable et possède plusieurs liens\n";
}

@infos_stat = CORE::stat($fichier); # Utilise la fonction interne,
                                    # même si elle est supplantée

Le module File::stat fournit une interface méthode aux fonctions internes Perl stat et lstat en les remplaçant par des versions renvoyant un objet File::stat (ou undef en cas d'échec). Cet objet possède des méthodes nommées de manière à renvoyer le champ de la structure du même nom depuis l'appel système habituel stat(2) ; il s'agit de dev, ino, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, blksize et blocks. Vous pouvez également importer les champs de la structure dans votre propre espace de noms en tant que variables ordinaires en utilisant le tag d'importation « :FIELDS ». (Les opérateurs internes stat et lstat continuent à être supplantés.) Ces champs se présentent comme des variables scalaires avec un « st_ » au début du nom du champ. C'est-à-dire que la variable $st_dev correspond à la méthode $st->dev.

32-25. File::Temp

 
Sélectionnez
use File::Temp qw(tempfile tempdir);

$rep = tempdir(CLEANUP => 1);
($hf, $fichier) = tempfile(DIR => $rep);
($hf, $fichier) = tempfile($exemple, DIR => $rep);
($hf, $fichier) = tempfile($exemple, SUFFIX => ".data");
$hf = tempfile();

use File::Temp ':mktemp';

($hf, $fichier) = mkstemp("fic_tmpXXXXX");
($hf, $fichier) = mkstemps("fic_tmpXXXXX", $suffixe);
$rep_tmp = mkdtemp($exemple);
$fichier_non_ouvert = mktemp($exemple);

Nouveauté dans la version 5.6.1 de Perl, le module File::Temp fournit des fonctions pratiques pour créer et ouvrir de manière sûre des fichiers temporaires. Il vaut mieux utiliser ce module qu'essayer de choisir vous-même un fichier temporaire. Sinon, vous tomberez dans les mêmes pièges que tout le monde avant vous. Ce module vous protège aussi bien des situations de concurrence (race conditions) que du danger d'employer des répertoires où d'autres peuvent écrire ; voir le chapitre 23, Sécurité. La fonction tempfile renvoie à la fois un handle de fichier et un nom de fichier. Le plus sûr est d'utiliser ce qui est déjà ouvert et d'ignorer complètement le nom de fichier (excepté peut-être pour les messages d'erreurs). Une fois que le fichier est fermé, il est automatiquement supprimé. Pour assurer une compatibilité avec la bibliothèque C, le tag d'importation :mktemp donne un accès aux fonctions dont les noms sont familiers aux programmeurs C, mais s'il vous plaît, souvenez-vous que les noms de fichiers sont toujours moins sûrs que les handles de fichiers.

32-26. FileHandle

 
Sélectionnez
use FileHandle;

$hf = new FileHandle;
if ($hf->open("< fichier")) {
    print $ligne while defined($ligne = $hf->getline);
    $hf->close;
}

$pos = $hf->getpos; # comme tell()
$hf->setpos($pos);  # comme seek()

($hf_lec, $hf_ecr) = FileHandle::pipe();

autoflush STDOUT, 1;

Le module FileHandle sert surtout de mécanisme pour dissimuler les variables de Perl contenant des ponctuations sous des appellations plus longues, davantage dans le style orienté objet. Il est fourni pour assurer une compatibilité avec des versions antérieures, mais maintenant il s'agit véritablement d'un frontal vers plusieurs modules plus spécifiques, comme IO::Handle et IO::File.(230) Sa meilleure propriété est l'accès de bas niveau qu'il fournit vers certaines fonctions rares de la bibliothèque C (clearerr(3), fgetpos(3), fsetpos(3) et setvbuf (3)).

Variable

Méthode

$|

autoflush

$,

output_field_separator

$\

output_record_separator

$/

input_record_separator

$.

input_line_number

$%

format_page_number

$=

format_lines_per_page

$-

format_lines_left

$~

format_name

$^

format_top_name

$:

format_line_break_characters

$^L

format_formfeed

Au lieu d'écrire :

 
Sélectionnez
$hfs = select(HANDLE );
$~ = 'UnFormat';
$|= 1;
select($hfs);

vous pouvez juste écrire :

 
Sélectionnez
use FileHandle;
Handle->format_name('UnFormat');
Handle->autoflush(1);

Actuellement, trois méthodes (output_field_separator, output_record_separator et input_record_separator) ne font que prétendre être des méthodes par handle : les positionner sur un handle affecte tous les handles de fichiers. Elles sont ainsi seulement supportées en tant que méthodes de classes, pas en tant que méthodes par handle de fichier. Cette restriction sera peut-être abandonnée un jour.

Pour obtenir un handle de fichier de portée lexicale, au lieu d'utiliser l'autovivifiation de handle de fichier :

 
Sélectionnez
open my $hf, "< un_fichier"
    or die "impossible d'ouvrir un_fichier : $!";

on peut écrire :

 
Sélectionnez
use FileHandle;
my $hf = FileHandle->new("< un_fichier")
    or die "impossible d'ouvrir un_fichier : $!";

FileHandle hérite de IO::File, qui lui-même hérite de IO::Handle et IO::Seekable. Les fonctionnalités du module sont virtuellement toutes accessibles plus efficacement via les appels purs et basiques de Perl, sauf pour les suivants, qui peuvent ne pas tous être implémentés sur les plates-formes non Unix :

HANDLE->blocking(EXPR)

  • Appelé avec un argument, active les entrées/sorties non bloquantes si l'argument est faux et désactive les entrées/sorties non bloquantes (c'est-à-dire active les entrées/sorties bloquantes) s'il est vrai. La méthode renvoie la précédente valeur positionnée (ce qui est toujours le comportement actuel si aucun argument n'est donné). En cas d'erreur, blocking positionne $! et renvoie undef. Ceci pourrait être accompli avec fcntl directement, mais l'interface FileHandle est plus simple à utiliser.

HANDLE->clearerr

  • Appelle la fonction clearerr(3) de la bibliothèque C pour efface les indicateurs internes du handle pour la fin de fichier et le statut d'erreur.

HANDLE->error

  • Appelle la fonction ferror(3) de la bibliothèque C pour tester l'indicateur d'erreur pour le handle donné, en renvoyant si cet indicateur interne est positionné ou non. L'indicateur d'erreur ne peut être réinitialisé fiablement que via la méthode clearerr. (Certains systèmes le réinitialisent également en appelant l'opérateur seek.)

HANDLE->formline(IMAGE, LISTE)

  • Cela revient au même que de sauvegarder l'ancienne variable d'accumulateur ($^A), d'appeler la fonction formline avec l'IMAGE et la LISTE données, d'afficher le contenu résultant de l'accumulateur vers le handle donné et enfin de restaurer l'accumulateur original. Par exemple, voici comment afficher une variable représentant un texte long en allant à la ligne à la colonne 72 :
 
Sélectionnez
use FileHandle;
STDOUT->formline("^" . ("<" x 72) . "~~\n", $texte_long);

HANDLE->getpos

  • Appelle la fonction getpos(3) de la bibliothèque C, offrant ainsi une interface alternative à tell. Sur certains systèmes (non Unix), la valeur renvoyée peut être un objet complexe et getpos et setpos peuvent être la seule manière de repositionner de manière portable un flux de texte.

HANDLE->new_tmpfile

  • Appelle la fonction tmpfile(3) de la bibliothèque C pour créer un nouveau fichier temporaire ouvert en mode lecture-écriture et renvoie un handle sur ce flux. Sur les systèmes où c'est possible, le fichier temporaire est anonyme, c'est-à-dire qu'il est supprimé avec unlink après sa création tout en restant ouvert. Vous devez utiliser cette fonction ou POSIX::tmpnam comme décrit dans le module POSIX pour créer de manière sûre un fichier temporaire sans vous exposer aux problèmes de sécurités annexes, mais néanmoins sérieux avec les situations de concurrence (N.d.T. : race conditions). Depuis la version 5.6.1 de Perl, le module File::Temp est maintenant l'interface recommandée.

HANDLE->setbuf(TAMPON)

  • Appelle la fonction setbuf (3) de la bibliothèque C avec la variable TAMPON donnée. La méthode passe undef pour indiquer une sortie qui n'utilise pas le mécanisme de tampon. Une variable utilisée comme tampon par setbuf ou setvbuf ne doit pas être modifiée d'aucune manière jusqu'à ce que le handle soit fermé ou jusqu'à ce que la fonction setbuf ou setvbuf soit appelée à nouveau. Sinon il peut en résulter une corruption de mémoire qui vous ferait de la peine.

HANDLE->setpos(EXPR)

  • Appelle la fonction fsetpos(3) de la bibliothèque C, offrant ainsi une autre interface à seek. L'argument ne doit être qu'une valeur correcte renvoyée par getpos, comme décrit précédemment.

HANDLE->setvbuf(TAMPON, TYPE, TAILLE)

  • Appelle la fonction setvbuf (3) de la bibliothèque C avec le TAMPON donné. Les constantes standards de la bibliothèque C _IONBF (sans utilisation d'un tampon), _IOLBF (tampon vidé ligne par ligne) et _IOFBF (mécanisme complet de tampon) sont disponibles pour le champ TYPE si elles sont explicitement importées. Voir la mise en garde dans setbuf.

HANDLE->sync

  • Appelle la fonction fsync(3) de la bibliothèque C pour synchroniser un fichier dans un état en mémoire vers le support physique. Remarquez que sync n'agit pas sur le handle mais sur le descripteur de fichier, toute donnée conservée dans les tampons ne sera donc pas synchronisée à moins que le tampon ne soit tout d'abord vidé (N.d.T. : flushed).

HANDLE->untaint

  • Marque le handle de fichier ou de répertoire en lui fournissant une donnée non marquée. Lorsque l'on tourne en mode marqué (voir le chapitre 23), les données lues depuis des fichiers externes sont considérées comme étant indignes de confiance. N'invoquez pas cette méthode aveuglément : vous court-circuiteriez les meilleures tentatives de Perl pour vous protéger de vous-même.

32-27. Getopt::Long

Si votre programme fait :

 
Sélectionnez
use Getopt::Long;
GetOptions("verbeux"  => \$verbeux,
           "debogage" => \$debogage,
           "sortie=s" => \$sortie);

il peut être appelé ainsi depuis la ligne de commande :

 
Sélectionnez
% prog --verbeux autres arguments ici
% prog --debogage autres arguments ici
% prog -v -d autres arguments ici
% prog --sortie=un_fichier autres arguments ici
% prog -s un_fichier autres arguments ici

Le module Getopt::Long fournit une fonction GetOptions pour traiter les options de la ligne de commande avec des noms assez longs. Il inclut un support pour des choses comme les options en abrégé, les arguments typés comme booléen, chaîne, entier ou à virgule flottante, les variables de tableaux pour les options répétées, les routines de validation définies par l'utilisateur, le traitement conforme à POSIX ou conforme au style FSF, les options insensibles à la casse et le regroupement traditionnel des options courtes pour ne citer qu'un échantillon de la corne d'abondance de ses fonctionnalités. Si ce module en fait trop, pensez au module plus ordinaire Getopt::Std décrit plus loin. Si ce module n'en fait pas assez, regardez le module de CPAN Getopt::Declare qui offre une syntaxe plus déclarative pour spécifier les options.

32-28. Getopt::Std

 
Sélectionnez
use Getopt::Std;

Vous pouvez utiliser getopt et getopts avec des variables globales :

 
Sélectionnez
out ($opt_o, $opt_i, $opt_f);
getopt('oif');   # -o, -i et -f prennent tous des arguments.
                 # Positionne les variables globales $opt_*.
getopts('oif:'); # Maintenant -o et -i sont booléens ; -f prend un arg.
                 # Positionne toujours les variables globales $opt_*
                 # comme effet de bord.

Ou vous pouvez les utiliser avec un hachage privé pour les options :

 
Sélectionnez
my %opts;                # Nous placerons les résultats ici.
getopt('oif', \%opts);   # Tous les trois prennent toujours un argument.
getopts('oif:', \%opts); # Maintenant -o et -i sont des booléens
                         # et seul -f prend un argument.

Le module Getopt::Std fournit deux fonctions, getopt et getopts, pour vous aider à analyser les arguments de la ligne de commande dans le cas d'options sur un seul caractère. Des deux fonctions, getopts est la plus utile, car elle vous laisse spécifier que certaines options prennent un argument ; sinon, on s'attend à trouver une option booléenne. Le regroupement d'options standards est supporté. L'ordre ne compte pas, ainsi les options ne prenant pas d'arguments peuvent être regroupées ensemble. Les options qui prennent un argument doivent être les dernières d'un groupe ou être spécifiées à part et leur argument doit venir soit immédiatement après l'option dans la même chaîne, soit comme l'argument suivant du programme. Étant donné l'exemple d'utilisation de getopts ci-dessus, voici des appels équivalents :

 
Sélectionnez
% prog -o -i -f FIC_TEMP autres arguments ici
% prog -o -if FIC_TEMP autres arguments ici
% prog -io -fFIC_TEMP autres arguments ici
% prog -iofFIC_TEMP autres arguments ici
% prog -oifFIC_TEMP autres arguments ici

32-29. IO::Socket

 
Sélectionnez
use IO::Socket;

En tant que client :

 
Sélectionnez
$socket = new IO::Socket::INET (PeerAddr => $hote_distant,
                                PeerPort => $port_distant,
                                Proto => "tcp",
                                Type => SOCK_STREAM)
    or die "Connexion impossible vers $hote_distant:port_distant : $!\n";

# Ou utilisez l'interface plus simple à un seul argument.
$socket = IO::Socket::INET->new("$hote_distant:$port_distant,");
                               # "localhost:80", par exemple.

print $socket "donnée\n";
$ligne = <$socket>;

En tant que serveur :

 
Sélectionnez
$serveur = IO::Socket::INET->new(LocalPort => port_serveur,
                                 Type => SOCK_STREAM,
                                 Reuse => 1,
                                 Listen => 10) # ou SOMAXCONN
    or die "Impossible d'être un serveur TCP sur le port
           $port_serveur : $!\n";

while ($client = $serveur->accept()) {
    # $client est la nouvelle connexion
    $requete = <$client>;
    print $client "reponse\n";
    close $client;
}

# Simple fonction de connexion TCP renvoyant un handle de fichier
# pour utiliser dans les programmes clients simples.
sub connex_tcp {
    my ($hote, $service) = @_;
    require IO::Socket;
    return IO::Socket::INET->new(join ":", $hote, $service);
}
my $hf = connex_tcp("localhost", "smtp");       # avec un scalaire
local *HF = connex_tcp("localhost", "smtp");    # avec un handle

Le module IO::Socket fournit une approche de plus haut niveau pour la gestion des sockets que le module de base Socket. Vous pouvez l'utiliser dans un style orienté objet, bien que ce ne soit pas obligatoire, car les valeurs renvoyées sont des handles de fichiers réguliers et peuvent être utilisées en tant que telles, comme le montre la fonction connex_tcp dans l'exemple ci-dessus. Ce module hérite ses méthodes de IO::Handle et fait lui-même un require de IO::Socket::INET et IO::Socket::UNIX. Voir la description du module FileHandle pour d'autres fonctionnalités intéressantes. Voir le chapitre 16 pour une description de l'utilisation des sockets.

32-30. IPC::Open2

 
Sélectionnez
use IPC::Open2;

local(*SA_SORTIE, *SON_ENTREE); # Crée les handles locaux si besoin.
$pid_fils = open2(*SA_SORTIE, *SON_ENTREE, $programme, @args)
    or die "Impossible d'ouvrir un pipe vers $programme : $!";
print SON_ENTREE "Voici votre entrée\n";
$sa_sortie = <SA_SORTIE>;
close(SA_SORTIE);
close(SON_ENTREE);
waitpid($pid_fils, 0);

La seule fonction exportée, open2, du module IPC::Open2 démarre un autre programme et offre un accès à la fois en lecture et en écriture à cette commande. Les deux premiers arguments doivent être des handles de fichiers valides (ou alors des variables vides dans lesquelles seront placés les handles de fichiers autogénérés). Les arguments restants sont le programme plus ses arguments, qui, s'ils sont passés séparément, ne seront pas interprétés par le shell. Ce module ne récolte pas le processus fils après sa mort. À part les programmes courts où il reste acceptable de laisser le système d'exploitation gérer cela, vous aurez besoin de le faire vous-mêmes. Cela se résume normalement à appeler waitpid $pid, 0 lorsque vous en avez fini avec ce processus fils. Ne pas faire ceci entraîne l'accumulation de processus défunts (« zombies »).

En pratique, ce module ne fonctionne pas bien avec beaucoup de programmes à cause de la manière dont marche le vidage de tampon dans la bibliothèque d'entrées/sorties standard en C. Si vous contrôlez le code source des deux programmes, vous pouvez toutefois contourner facilement cette restriction en forçant le vidage ( flushing) de vos tampons de sortie plus fréquemment que par défaut. Si ce n'est pas le cas, les programmes peuvent être ennuyeusement avares dans leur accumulation de données en sortie. Un autre piège potentiel est le verrou mortel (deadlock) : si les deux processus sont en train de lire au même moment et qu'aucun n'écrit, alors votre programme se bloquera. Voir le chapitre 16 pour une discussion approfondie.

32-31. IPC::Open3

 
Sélectionnez
use IPC::Open3;

local(*SON_ENTREE, *SA_SORTIE, *SON_ERREUR);

$pid_fils = open3(*SON_ENTREE, *SA_SORTIE, *SON_ERREUR, $cmd, @args);
print SON_ENTREE "trucs\n";
close(SON_ENTREE);              # Donne une fin de fichier au fils.
@lignes_sortie = <SA_SORTIE>;   # Lit jusqu'à EOF.
@lignes_erreur = <SON_ERREUR>;  # XXX : blocage potentiel si énorme
print "STDOUT:\n", @lignes_sortie, "\n";
print "STDERR:\n", @lignes_erreur, "\n";
close SA_SORTIE;
close SON_ERREUR;
waitpid($pid_fils, 0);
if ($?) {
    print "Ce fils s'est terminé avec comme statut d'attente $?_n";
}

Le module IPC::Open3 fonctionne comme IPC::Open2 (ce dernier est implémenté dans les termes du premier), excepté que open3 donne accès aux handles d'entrée standard, de sortie standard et de sortie d'erreurs standard du programme que vous lancez. Les mêmes précautions qu'avec open2 (voir l'entrée précédente) s'appliquent, plus quelques autres. Au lieu de passer le handle pour la lecture en premier et celui pour l'écriture en second, cette fois-ci c'est l'inverse. De plus, avec open3, le danger de verrous mortels (deadlocks) est encore plus grand qu'avant. Si vous essayez de lire après la fin de fichier sur l'un des handles de sortie du fils, mais que pendant ce temps il y a beaucoup de trafic en sortie sur l'autre handle, le processus pair semble se bloquer. Utilisez soit la forme à quatre arguments de select, soit le module IO::Select pour contourner cela. Voir le chapitre 16 pour plus de détails.

32-32. Math::BigInt

 
Sélectionnez
use Math::BigInt;
$i = Math::BigInt->new($chaine);

use Math::BigInt ':constant';
print 2**200;

Ceci affiche :

 
Sélectionnez
+1606938044258990275541962092341162602522202993782792835301376

Le module Math::BigInt fournit des objets qui représentent des entiers avec une précision arbitraire et des opérateurs arithmétiques surchargés. Créez ces objets en utilisant le constructeur new ou, dans une portée lexicale, en important la valeur spéciale « :constant », après laquelle tous les littéraux numériques jusqu'à la fin de cette portée lexicale seront traités comme des objets Math::BigInt. Tous les opérateurs standards sur les entiers sont implémentés, y compris (depuis la version 5.6 de Perl) les opérateurs logiques de bits. Dans l'implémentation actuelle, ce module n'est pas ce que vous pouvez appeler d'une rapidité fulgurante, mais cela pourrait être le cas dans l'avenir. (Nous aimerions voir à quelle vitesse vous calculez de tête 2**200.)

32-33. Math::Complex

 
Sélectionnez
use Math::Complex;

$z = Math::Complex->make(5, 6);
$z = cplx(5, 6);        # idem, mais plus court.
$t = 4 - 3*i + $z;      # effectue des opérations complexes standard
print "$t\n";           # affiche 9+3i
print sqrt(-9), "\n";   # affiche 3i

Le module Math::Complex fournit des objets représentant des nombres complexes avec des opérateurs surchargés. Ce sont des nombres avec une partie réelle et une partie imaginaire comme ceux qui satisfont les racines paires de nombres négatifs, comme montré ci-dessus. À côté des opérateurs arithmétiques, nombre de fonctions internes mathématiques sont également supplantées par des versions qui connaissent les nombres complexes, incluant abs, log, sqrt, sin, cos et atan2. D'autres fonctions fournies sont Re et Im pour donner les parties réelles et imaginaires des arguments complexes, plus une batterie complète de fonctions trigonométriques étendues, comme tan, asin, acos, sinh, cosh et tanh. Le module exporte également la constante i, qui, comme vous pouvez l'imaginer, contient la valeur de i ; c'est-à-dire, la racine carrée de -1.

32-34. Math::Trig

 
Sélectionnez
use Math::Trig;

$x = tan(0.9);
$y = acos(3.7);
$z = asin(2.4);

$pi_sur_deux = pi/2;

$rad = deg2rad(120);

Perl ne définit lui-même que trois fonctions trigonométriques : sin, cos et atan2. Le module Math::Trig les supplante avec des versions plus agréables et fournit toutes les autres fonctions trigos, incluant tan, csc, cosec, sec, cot, cotan, asin, acos, atan, sinh, cosh, tanh et beaucoup d'autres. De plus, la constante pi est définie, tout comme les fonctions de conversion comme deg2rad et grad2rad. Un support est fourni pour les systèmes de coordonnées cartésiennes, cylindriques ou sphériques. Ce module fait un usage implicite de Math::Complex si besoin est (et vice-versa) pour les calculs nécessitant des nombres imaginaires.

32-35. Net::hostent

 
Sélectionnez
use Socket;
use Net::hostent;

print inet_ntoa(gethost("www.perl.com")->addr); # affiche 208.201.239.50
printf "%vd", gethost("www.perl.com")->addr;    # idem

print gethost("127.0.0.1")->name;               # affiche localhost

use Net::hostent ':FIELDS';
if (gethost($nom_ou_nombre)) {
    print "le nom est $h_name\n";
    print "les alias sont $h_aliases\n";
    print "les adresses sont ",
    join ", " => map { inet_ntoa($_) } @h_addr_list;
}

Les exportations par défaut de ce module supplantent les fonctions intrinsèques gethostbyname et gethostbyaddr, en les remplaçant avec des versions qui renvoient un objet Net::hostent (ou undef en cas d'échec). Cet objet possède des méthodes accesseurs d'attributs qui renvoient des champs nommés comme ceux de la structure struct hostent de la bibliothèque C définie dans netdb.h : name, aliases, addrtype, length ou addr_list. Les méthodes aliases et addr_list renvoient des références de tableaux ; les autres renvoient des scalaires. La fonction gethost est un frontal qui fait suivre un argument numérique à gethostbyaddr par le biais de la fonction Socket::inet_aton et le reste à gethostbyname. Comme avec les autres modules semi-pragmatiques qui supplantent des fonctions internes renvoyant des listes, si vous importez le tag « :FIELDS », vous pouvez accéder à des variables de paquetages scalaires ou tabulaires par le même nom que les appels de méthodes préfixés par « h_ ». Les fonctions intrinsèques sont quand même supplantées.

32-36. POSIX

 
Sélectionnez
use POSIX;

# Arrondit des nombres à virgule flottante à l'entier supérieur
# ou inférieur le plus proche.
$n = ceil($n); # arrondi supérieur
$n = floor($n); # arrondi inférieur

# Produit "20-04-2001" pour aujourd'hui.
$ch_date = strftime("%d-%m-%Y"), localtime);

# Produit "vendredi 04/20/01" pour la même date.
$ch_date = strftime("%A %D"), localtime);

# Essaie de nouveaux noms de fichiers temporaires jusqu'à en trouver un qui
# n'existe pas déjà; voir également File::Temp sur CPAN ou dans la v5.6.1.
do {
    $nom = tmpnam();
} until sysopen(HF, $nom, O_CREAT|O_EXCL|O_RDWR, 0666);

# Vérifie si le système a un opérateur chown peu sûr le trahissant.
if (sysconf(_PC_CHOWN_RESTRICTED)) {
    print "Hourra -- seul le super-utilisateur peut appeler chown\n";
}

# Trouve les informations par uname du système courant.
my ($noyau, $hote, $release, $version, $materiel) = uname();

use POSIX ":queue";
while (($pid_mort = waitpid(-1, &WNOHANG)) > 0) {
    # Faites quelque chose avec $pid_mort si vous le voulez.
}

# Devient le leader d'une nouvelle session/nouveau groupe de processus
# (nécessaire pour créer des démons non affectés par les signaux
# du clavier ou les shells de connexion se terminant).
setsid(0) or die "échec de setsid : $!";

Le module POSIX de Perl vous permet d'accéder à tous (ou presque tous) les identificateurs du standard POSIX 1003.1, plus quelques-uns du C ANSI que nous ne savions pas où mettre. Ce module fournit plus de fonctions qu'aucun autre. Voir sa documentation en ligne pour une séance de dissection ou le POSIX Programmer's Guide de Donald Lewine (O'Reilly, 1991).

Les identificateurs qui sont des #defines sans paramètres en C, comme EINTR ou O_NDELAY sont automatiquement exporter dans votre espace de noms en tant que fonctions constantes. Les fonctions qui ne sont normalement pas disponibles en Perl (comme floor, ceil, strftime, uname, setsid, setlocale et sysconf) sont exportées par défaut. Les fonctions du même nom que les opérateurs internes de Perl, comme open, ne sont pas exportées à moins de le demander explicitement, mais la plupart de gens sont susceptibles de préférer des noms de fonctions pleinement qualifiés pour distinguer POSIX::open de CORE::open.

Quelques fonctions ne sont pas implémentées, car elles sont spécifiques au C. Si vous tentez de les appeler, elles affichent un message vous disant qu'elles ne sont pas implémentées et vous suggèrent d'utiliser un équivalent Perl s'il en existe. Par exemple, une tentative d'accéder à la fonction setjmp affiche le message « setjmp() is C-specific: use eval {} instead » et tmpfile vous dit « Use method IO::File::new_tmp_file() ». (Mais depuis la version 5.6.1, vous devriez plutôt utilisez File::Temp.)

Le module POSIX vous emmène aussi près du système d'exploitation (ou tout du moins aux parties adressées par le standard POSIX) que ne le ferait n'importe quel programmeur C. Ceci vous donne accès à un pouvoir phénoménal et à des choses très utiles, comme bloquer les signaux et contrôler les options des entrées/sorties du terminal. Toutefois, cela signifie également que votre code finira par ressembler quasiment à du C. Comme démonstration utile de la manière d'éviter les vidages de tampons en entrée, voici un exemple d'un programme complet pour obtenir un seul caractère en entrée sans tampon, sur un système POSIX :

 
Sélectionnez
#!/usr/bin/perl -w
use strict;
$| = 1;
for (1..4) {
    my $lu;
    print "donnez-moi : ";
    $lu = lire_un();
    print "--> $lu\n";
}
exit;

BEGIN {
    use POSIX qw(:termios_h);
    my ($term, $oterm, $echo, $noecho, $df_entree);
    $df_entree = fileno(STDIN);
    $term = POSIX::Termios->new();
    $term->getattr($df_entree);
    $oterm  = $term->getlflag();
    $echo   = ECHO | ECHOK | ICANON;
    $noecho = $oterm & ~$echo;
    sub cbreak {
        $term->setlflag($noecho);
        $term->setcc(VTIME, 1);
        $term->setattr($df_entree, TCSANOW);
    }
    sub cuisine {
        $term->setflag($oterm);
        $term->setcc(VTIME, 0);
        $term->setattr($df_entree, TCSANOW);
    }
    sub lire_un {
        my $clef = "";
        cbreak();
        sysread(STDIN, $clef, 1);
        cuisine();
        return $clef;
    }
}
END { cuisine() }

La page de man du module POSIX donne un inventaire complet des fonctions et constantes qu'il exporte. Il y en a tant que vous finirez souvent par n'en importer qu'un sous-ensemble, comme « :queue », « :sys_stat_h » ou « :termios_h ». Un exemple de blocage de signaux avec le module POSIX est donné au chapitre 16.

32-37. Safe

 
Sélectionnez
use Safe;

$mem_proteg = Safe->new();                # espace mémoire protégé anonyme
$mem_proteg = Safe->new("Nom_Paquetage"); # dans cette table de symboles

# Active ou désactive les codes d'opération par groupe ou par nom
$mem_proteg->permit(qw(:base_core));
$mem_proteg->permit_only(qw(:base_core :base_loop :base_mem));
$mem_proteg->deny("die");

# comme do(), mais dans l'espace mémoire protégé
$ok = $mem_proteg->rdo($fichier);

# comme eval(), mais dans l'espace mémoire protégé
$ok = $mem_proteg->reval($code);          # sans 'use strict'
$ok = $mem_proteg->reval($code, 1);       # avec 'use strict'

Le module Safe tente de fournir un environnement restreint pour protéger le reste du programme des opérations dangereuses. Il utilise deux stratégies différentes pour accomplir ceci. Un peu comme l'utilisation de chroot(2) par les démons FTP anonymes altère la vue que l'on a de la racine du système de fichier, la création d'un objet compartiment avec Safe->new("Nom_Paquetage") altère la vue que ce compartiment a de son propre espace de noms. Le compartiment voit maintenant comme sa table de symboles racine (main::), la table de symboles que le reste du programme voit comme Nom_Paquetage::. Ce qui ressemble à Bidule:: à l'intérieur du compartiment est en réalité Nom_Paquetage::Bidule:: à l'extérieur. Si vous ne donnez pas d'argument au constructeur, un nouveau nom de paquetage aléatoire est sélectionné pour vous. Le second et le plus important service fourni par un compartiment Safe est une manière de limiter le code considéré comme légal à l'intérieur d'un eval. Vous pouvez ajuster l'ensemble des codes d'opérations (opcodes) autorisés en utilisant des appels de méthodes sur votre objet Safe. Deux méthodes sont disponibles pour compiler du code dans un compartiment Safe : rdo (« restriction du do ») pour les fichiers et reval (« restriction de l'eval ») pour les chaînes. Ils fonctionnent comme do sur un nom de fichier et comme eval sur une chaîne, mais ils s'exécutent dans un espace de noms restreint avec des codes d'opérations limités. Le premier argument est le nom du fichier ou la chaîne à compiler et le second, qui est optionnel, indique si le code doit être compilé sous use strict ou pas.

Il est prévu de réécrire ce module (nous avons l'intention d'isoler l'espace mémoire protégé dans une tâche (thread) d'interpréteur différente pour une sécurité supplémentaire), assurez-vous donc de vérifier la page de man de Safe pour les mises à niveau. Voir également le chapitre 23.

32-38. Socket

 
Sélectionnez
use Socket;

$proto = getprotobyname('udp');
socket(SOCK , PF_INET, SOCK_DGRAM, $proto)
    or die "socket : $!";
$iadr = gethostbyname('hishost.com');
$port = getservbyname('time', 'udp');
$sin = sockaddr_in($port, $iadr);
send(SOCK, 0, 0, $sin)
    or die "send : $!";

$proto = getprotobyname('tcp');
socket(SOCK, PF_INET, SOCK_STREAM, $proto)
    or die "socket : $!";
$port = getservbyname('smtp', 'tcp');
$sin = sockaddr_in($port, inet_aton("127.1"));
$sin = sockaddr_in(7, inet_aton("localhost"));
$sin = sockaddr_in(7, INADDR_LOOPBACK);
connect(SOCK, $sin)
    or die "connect : $!";

($port, $iadr) = sockaddr_in(getpeerbyname(SOCK ));
$hote_pair = gethostbyaddr($iadr, AF_INET);
$adr_pair = inet_ntoa($iadr);

$proto = getprotobyname('tcp');
socket(SOCK, PF_UNIX, SOCK_STREAM, $proto)
    or die "socket : $!";

unlink('/tmp/usock'); # XXX : l'échec est ignoré intentionnellement
$sun = sockaddr_un('tmp/usock');
connect(SOCK, $sun)
    or die "connect : $!";

use Socket qw(:DEFAULT :crlf);
# Maintenant vous pouvez utiliser CR(), LF() et CRLF() ou
# $CR, $LF et $CRLF pour les fins de lignes.

Le module Socket donne accès aux constantes du fichier #include sys/socket.h de la bibliothèque C pour qu'on les utilise dans les fonctions de bas niveau de Perl concernant les sockets. Il fournit également deux fonctions, inet_aton et inet_ntoa, pour convertir les adresses IP entres leurs représentations ASCII (comme « 127.0.0.1 ») et leur empaquetage réseau, ainsi que deux fonctions spéciales d'empaquetage/dépaquetage, sockaddr_in et sockaddr_un, qui manipulent les adresses de sockets binaires nécessaires aux appels bas niveau. Le tag d'importation :crlf donne des noms symboliques aux conventions diverses de fin de ligne afin que vous n'ayez pas à vous fier aux interprétations natives de \r et \n, qui peuvent varier. La plupart des protocoles de l'Internet préfèrent CRLF, mais tolèrent LF. Le module standard IO::Socket fournit une interface de plus haut niveau à TCP. Voir le chapitre 16.

32-39. Symbol

 
Sélectionnez
use Symbol "delete_package";
delete_package("Truc::Bidule");
print "supprimé\n" unless exists $Truc::{"Bidule::"};

use Symbol "gensym";
$sym1 = gensym();                    # Renvoie un nouveau typeglob anonyme.
$sym2 = gensym();                    # Et encore un autre.

package Demo;
use Symbol "qualify";
$sym = qualify("x");                 # "Demo::x"
$sym = qualify("x", "Truc");         # "Truc::x"
$sym = qualify("Bidule::x");         # "Bidule::x"
$sym = qualify("Bidule::x", "Truc"); # "Bidule::x"

use Symbol "qualify_to_ref";
    sub pass_handle(*) {
    my $hf = qualify_to_ref(shift, caller);
    ...
}
# Maintenant vous pouvez appeler pass_handle avec HF, "HF", *HF ou \*HF.

Le module Symbol fournit des fonctions pour faciliter la manipulation des noms globaux : les typeglobs, les noms de formats, les handles de fichiers, les tables de symboles de paquetages et toute autre chose que vous pourriez vouloir nommer via une table de symboles. La fonction delete_package nettoie complètement l'espace de nom d'un paquetage (en rendant effectivement anonymes toutes références supplémentaires aux référants de la table de symboles, y compris les références de code précompilé). La fonction gensym renvoie un typeglob anonyme chaque fois qu'elle est appelée. (Cette fonction n'est plus tellement utilisée de nos jours, maintenant que les scalaires indéfinis s'autovivifient avec les handles de fichiers appropriés lorsqu'ils sont utilisés comme arguments de open, pipe, socket et leurs semblables.)

La fonction qualify prend un nom qui peut être complètement qualifié avec un paquetage, ou pas, et renvoie un nom qui l'est. Si elle a besoin de préfixer le nom du paquetage, elle utilisera le nom spécifié via le second argument (ou s'il est omis, votre nom de paquetage courant). La fonction qualify_to_ref fonctionne de la même manière, mais produit une référence au typeglob que le symbole représenterait. Ceci est important dans les fonctions qui requièrent qu'ils soient passés en tant que références. En convertissant cet argument avec qualify_to_ref, vous pouvez maintenant utiliser le handle fourni même avec strict refs activé. Vous pouvez également le consacrer avec bless dans une forme objet, puisqu'il s'agit d'une référence valide.

32-40. Sys::Hostname

 
Sélectionnez
use Sys::Hostname;
$hote = hostname();

Le module Sys::Hostname ne fournit qu'une seule fonction, hostname, qui compense ce fait en se remuant le derrière pour essayer de deviner comment votre hôte courant s'appelle. Sur les systèmes qui supportent l'appel système standard gethostname(2), celui-ci est utilisé, comme il s'agit de la méthode la plus efficace.6 Sur les autres systèmes, l'affichage de l'appel standard hostname(1) est employé. Sur d'autres encore, on appelle la fonction uname(3) de votre bibliothèque C, laquelle est également accessible par la fonction POSIX::uname de Perl. Si ces stratégies échouent toutes, d'autres efforts héroïques sont tentés. Quelles que soient les opinions de votre système sur ce qui est sensé ou insensé, Perl essaie de son mieux pour faire avec. Sur certains systèmes, ce nom d'hôte peut ne pas être pleinement qualifié avec le nom de domaine ; voir le module Net::Domain de CPAN si vous avez besoin de cela.

Il faut également prendre en considération que hostname ne renvoie qu'une seule valeur, mais que votre système peut avoir plusieurs interfaces réseaux configurées, vous pouvez donc ne pas vous voir renvoyer le nom associé à l'interface à laquelle vous vous intéressez si vous prévoyez d'utiliser ce module pour certains types de programmation de sockets. Il s'agit des cas où vous devrez probablement glaner dans l'affichage de la commande ifconfig(8) ou dans l'équivalent moral sur votre système.

32-41. Sys::Syslog

 
Sélectionnez
use Sys::Syslog;                         # Perd setlogsock.
use Sys::Syslog qw(:DEFAULT setlogsock); # Obtient également setlogsock.

openlog($programme, 'cons,pid', 'user');
syslog('info', 'ceci est un autre test');
syslog('mail|warning', 'ceci est un meilleur test : %d', time());
closelog();

syslog('debug', 'ceci est le dernier test');

setlogsock('unix');
openlog("$programme $$", 'ndelay', 'user');
syslog('info', 'le problème était %m');  # %m = $! pour le journal système
syslog('notice', 'prog_truc : ceci est vraiment terminé');

setlogsock('unix');                      # "inet" ou "unix"
openlog("mon_programme", $logopt, $services);
syslog($priorite, $format, @args);
$ancien_masque = setlogmask($priorite_masque);
closelog();

Le module Sys::Syslog se comporte comme la fonction syslog(3) de votre bibliothèque C, en envoyant des messages au démon de votre journal système, syslogd(8). Il est particulièrement utile dans les démons ou d'autres programmes qui ne disposent pas de terminal pour recevoir les affichages de diagnostics ou pour des programmes préoccupés par la sécurité qui veulent produire un enregistrement plus durable de leurs actions (ou des actions de quelqu'un d'autre). Les fonctions supportées sont :

openlog IDENT, LISTE_OPT, SERVICES

  • Établit une connexion avec votre amical démon syslog. IDENT est la chaîne sous laquelle enregistrer le message (comme $0, le nom de votre programme). LISTE_OPT est une chaîne avec des options séparées par des virgules comme « cons », « pid » et « ndelay ». SERVICES est quelque chose comme « auth », « daemon », « kern », « lpr », « mail », « news » ou « user » pour les programmes système et parmi « local0 » .. « local7 » pour les programmes locaux. Davantage de messages sont enregistrés en utilisant un service donné et la chaîne identificatrice.

syslog PRIORITE, FORMAT, ARGS

  • Envoie un message au démon en employant la PRIORITE donnée. Le FORMAT est exactement comme printf en comblant les séquences d'échappement des pourcentages avec les ARGS qui suivent excepté le fait qu'en respectant les conventions de la fonction syslog(3) de la bibliothèque standard, la séquence spéciale « %m » est interpolée avec errno (la variable $! de Perl) à cet endroit.

setlogsock TYPE

  • TYPE doit valoir soit « inet », soit « unix ». Certains démons de systèmes ne font pas attention par défaut aux messages de syslog provenant du domaine Internet, vous pouvez alors lui affecter « unix » à la place, puisqu'il ne s'agit pas de la valeur par défaut.

closelog

  • Rompt la connexion avec le démon.

Pour que ce module fonctionne avec les versions de Perl antérieures à la 5.6.0, votre administrateur système doit lancer h2ph(1) sur votre fichier d'en-tête sys/syslog.h pour créer un fichier de bibliothèque sys/syslog.ph. Toutefois, ceci n'était pas accompli par défaut à l'installation de Perl. Les versions ultérieures utilisent maintenant une interface XS, la préparation de sys/syslog.ph n'est donc plus nécessaire.

32-42. Term::Cap

 
Sélectionnez
use Term::Cap;

$ospeed = eval {
    require POSIX;
    my $termios = POSIX::Termios->new();
    $termios->getattr;
    $termios->getospeed;
} || 9600;

$terminal = Term::Cap->Tgetent({ TERM => undef, OSPEED => $ospeed });
$terminal->Tputs('cl', 1, STDOUT);          # Efface l'écran.
$terminal->Tgoto('cm', $col, $lig, STDOUT); # Déplace le curseur.

Le module Term::Cap donne accès aux routines termcap(3) de votre système. Voir la documentation de votre système pour plus de détails. Les systèmes qui ne disposent que de terminfo(5), mais pas de termcap(5) échoueront. (Beaucoup de systèmes terminfo peuvent émuler termcap.) Toutefois, vous trouverez sur CPAN un module Term::Info ainsi que Term::ReadKey, Term::ANSIColor et divers modules Curses pour vous aider avec les entrées caractère par caractère, les affichages en couleur ou la gestion des écrans de terminaux à un niveau plus élevé que Term::Cap ou Term::Info.

32-43. Text::Wrap

 
Sélectionnez
use Text::Wrap; # Importe wrap().

@lignes = (< <"FIN_G&S" =~ /\\S.*\S/g);

    Ceci est particulièrement rapide,
    un boniment inintelligible
    n'est généralement
    pas entendu,
    et s'il
    l'est, on
    s'en fiche.

FIN_G&S

$Text::Wrap::columns = 50;
print wrap(" " x 8, " " x 3, @lignes), "\n";

Ceci affiche :

 
Sélectionnez
Ceci est particulièrement rapide, un boniment inintelligible n'est généralement pas entendu, et s'il l'est, on s'en fiche.

Le module Text::Wrap implémente un formateur de paragraphes simples. Sa fonction wrap formate un simple paragraphe à la fois en coupant les lignes sans le faire au milieu d'un mot. Le premier argument est le préfixe ajouté au début de la première ligne renvoyée. Le second est la chaîne utilisée comme préfixe pour toutes les lignes sauf la première. Tous les arguments suivants sont joints en utilisant un saut de ligne comme séparateur et ils sont renvoyés comme une seule chaîne de paragraphe reformatée. Vous devez apprécier vous-même la largeur de votre terminal ou au moins spécifier ce que vous désirez dans $Text::Wrap::columns. Bien que l'on puisse utiliser l'appel ioctl TIOCWINSZ pour apprécier le nombre de colonnes, il serait plus facile pour ceux qui ne sont pas habitués à la programmation en C, d'installer le module Term::Readkey de CPAN et d'utiliser la routine GetTerminalSize de ce module.

32-44. Time::Local

 
Sélectionnez
use Time::Local;
$date = timelocal($sec,$min,$heures,$jour_m,$mois,$annee);
$date = timegm($sec,$min,$heures,$jour_m,$mois,$annee);

$date = timelocal(50, 45, 3, 18, 0, 73);
print "scalar localtime donne : ", scalar(localtime($date)), "\n";
$date += 28 * 365.2425 * 24 * 60 * 60;
print "Vingt-huit années plus tard, il est maintenant\n\t",
    scalar(localtime($date)), "\n";

Ceci affiche :

 
Sélectionnez
scalar localtime donne : Thu Jan 18 03:45:50 1973
Vingt-huit années plus tard, il est maintenant
        Wed Jan 17 22:43:26 2001

Le module Time::Local fournit deux fonctions, timelocal et timegm, qui fonctionne exactement à l'inverse des fonctions localtime et gmtime, respectivement. C'est-à-dire qu'elles prennent une liste de valeurs numériques pour les divers composants de ce que localtime renvoie dans un contexte de liste et déterminent quel paramètre passé en entrée à localtime aurait produit ces valeurs. Vous pouvez utiliser ceci si vous voulez comparer ou lancer des calculs sur deux dates différentes. Bien que ces fonctions ne soient pas génériques pour analyser les dates et les heures, si vous pouvez vous arranger pour avoir vos paramètres dans le bon format, elles sont souvent suffisantes. Comme vous pouvez le voir dans l'exemple ci-dessus, la date et l'heure possèdent tout de même quelques excentricités et même de simples calculs échouent souvent pour faire ce qu'on leur demande à cause des années bissextiles, des secondes intercallaires et de la phase de la lune. Deux modules de CPAN, énormes, mais complets, s'occupent de ces problèmes et bien plus encore : Date::Calc et Date::Manip.

32-45. Time::localtime

 
Sélectionnez
use Time::localtime;
print "L'année est %d\n", localtime->year() +1900;

$maintenant = ctime();

use Time::localtime;
use File::stat;
$date_chaine = ctime(stat($fichier)->mtime);

Ce module supplante la fonction intrinsèque localtime en la remplaçant avec une version qui renvoie un objet Time::tm (ou undef en cas d'échec). Le module Time::gmtime fait de même, mais il remplace la fonction intrinsèque gmtime à la place. L'objet renvoyé possède des méthodes qui accèdent aux champs nommés comme ceux de la structure struct tm dans time.h de la bibliothèque C : sec, min, hour, mday, mon, year, wday, yday et isdst. La fonction ctime donne un moyen d'obtenir la fonction originale (dans son sens scalaire) CORE::localtime. Remarquez que les valeurs renvoyées proviennent directement d'une structure struct tm, elles se situent donc dans les mêmes intervalles, voir l'exemple ci-dessus pour la manière correcte de produire une année sur quatre chiffres. La fonction POSIX::strftime est encore plus utile pour formater les dates et les heures avec une grande variété de styles plus alléchants les uns que les autres.

32-46. User::grent

 
Sélectionnez
use User::grent;
$gr = getgrgid(0)       or die "Pas de groupe zéro";
if ($gr->name eq "audio" && @{$gr->members} > 1) {
    print "le gid zéro s'appelle audio et compte d'autres membres";
}

$gr = getgr($n_importe_qui); # Accepte à la fois une chaîne ou un nombr

use User::grent ':FIELDS';
$gr = getgrgid(0)       or die "Pas de groupe zéro";
if ($gr_name eq "audio" && @gr_members > 1) {
    print "le gid zéro s'appelle audio et compte d'autres membres";
}

Les exportations par défaut de ce module supplantent les fonctions intrinsèques getgrent, getgruid et getgrnam, en les remplaçant par des versions qui renvoient un objet User::grent (ou undef en cas d'échec). Cet objet possède des méthodes qui accèdent aux champs nommés comme ceux de la structure struct group dans grp.h de la bibliothèque C : name, passwd, gid et members (et pas mem comme en C !). Les trois premières renvoient des scalaires et la dernière une référence de tableau. Vous pouvez également importer les champs de la structure dans votre propre espace de noms en tant que variables ordinaires en utilisant le tag d'importation « :FIELDS », bien que ceci supplante toujours les fonctions intrinsèques. Les variables (les trois scalaires et le tableau) sont préfixées par « gr_ ». La fonction getgr est une simple bascule frontale qui fait suivre tout argument numérique à getgrid et tout argument chaîne à getgrnam.

32-47. User::pwent

 
Sélectionnez
# Par défaut, supplante seulement les fonctions intrinsèques.
use User::pwent;
$pw = getpwnam("daemon") or die "Pas d'utilisateur daemon";
if ($pw->uid == 1 && $pw->dir =~ m#^/(bin|tmp)?$# ) {
    print "uid 1 sur le répertoire racine";
}

$pw = getpw($n_importe_qui); # Accepte à la fois une chaîne ou un nombre.
$shell_reel = $pw->shell || '/bin/sh';
for (($nom_complet, $bureau, $tel_bur, $tel_maison) =
      split /\s*,\s*/, $pw->gecos)
{
    s/&/ucfirst(lc($pw->name))/ge;
}

# positionne des variables globales dans le paquetage courant.
use User::pwent qw(:FIELDS);
$pw = getpwnam("daemon") or die "Pas d'utilisateur daemon";
if ($pw_uid == 1 && $pw_dir =~ m#^/(bin|tmp)?$# ) {
    print "uid 1 sur le répertoire racine";
}

use User::pwent qw/pw_has/;
if (pw_has(qw[gecos expire quota])) { ... }
if (pw_has("name uid gid passwd")) { ... }
printf "Votre struct pwd supporte [%s]\n", scalar pw_has();

Les exportations par défaut de ce module supplantent les fonctions intrinsèques getpwent, getpwuid et getpwnam, en les remplaçant par des versions qui renvoient un objet User::pwent (ou undef en cas d'échec). Il est souvent préférable d'utiliser ce module plutôt que les fonctions intrinsèques qu'il remplace, car les fonctions intrinsèques surchargent, voire omettent divers éléments dans la liste renvoyer au nom de la compatibilité ascendante.

L'objet renvoyé possède des méthodes qui accèdent aux champs nommés comme ceux de la structure passwd dans pwd.h de la bibliothèque C, avec le préfixe « pw_ » en moins : name, passwd, uid, gid, change, age, quota, comment, class, gecos, dir, shell et expire. Les champs passwd, gecos et shell sont marqués. Vous pouvez également importer les champs de la structure dans votre propre espace de noms en tant que variables ordinaires en utilisant le tag d'importation « :FIELDS », bien que ceci supplante toujours les fonctions intrinsèques. Vous accédez à ces champs en tant que variables scalaires nommées avec un préfixe « pw_ » devant le nom de la méthode. La fonction getpw est une simple bascule frontale qui fait suivre tout argument numérique à getpwuid et tout argument chaîne à getpwnam.

Perl croit qu'aucune machine n'a plus d'un champ parmi change, age ou quota d'implémenté, ni plus d'un parmi comment ou class. Certaines machines ne supportent pas expire, gecos, on dit que certaines machines ne supportent même pas passwd. Vous pouvez appeler ces méthodes, quelle que soit la machine sur laquelle vous êtes, mais elles retourneront undef si elles ne sont pas implémentées. Voir passwd(5) et getpwent(3) pour plus de détails.

Vous pouvez déterminer si ces champs sont implémentés en le demandant à la fonction non portable pw_has. Elle renvoie vrai si tous les paramètres sont des champs supportés sur la plate-forme ou faux si au moins un ne l'est pas. Elle lève une exception si vous demandez un champ dont le nom n'est pas reconnu. Si vous ne passez aucun argument, elle renvoie la liste des champs que votre bibliothèque C pense qu'ils sont supportés.

L'interprétation du champ gecos varie entre les systèmes, mais il comprend souvent quatre champs séparés par des virgules contenant le nom complet de l'utilisateur, l'emplacement de son bureau, son téléphone professionnel et son téléphone personnel. Un & dans le champ gecos doit être remplacé par le nom de login, name, de l'utilisateur avec les majuscules et minuscules correctes. Si le champ shell est vide, on suppose qu'il vaut /bin/sh, bien que Perl ne le fasse pas pour vous. Le passwd est donnée par une fonction de hachage à sens unique produisant du charabia au lieu d'un texte lisible, et on ne peut inverser la fonction de hachage en essayant brutalement toutes les combinaisons possibles. Les systèmes sécurisés utilisent souvent une fonction de hachage plus sûre que DES. Sur les systèmes supportant les mots de passe cachés, Perl renvoie automatiquement l'entrée du mot de passe sous sa forme cachée lorsqu'un utilisateur suffisamment puissant l'appelle, même si la bibliothèque C sous-jacente fournie par votre constructeur avait une vision trop courte pour réaliser qu'il aurait dû faire cela.

33. Messages de diagnostic

Ces messages sont classés dans un ordre croissant de désespoir :

Classe

Signification

(W)

Un avertissement (optionnel).

(D)

Une obsolescence (optionnelle).

(S)

Un avertissement sérieux (obligatoire).

(F)

Une erreur fatale (interceptable).

(P)

Une erreur interne (panique) que vous ne devriez jamais rencontrer (interceptable).

(X)

Une erreur extrêmement fatale (non-interceptable).

(A)

Une erreur venue de l'au-delà (non générée par Perl).

La plupart des messages des trois premières classifications ci-dessus (W, D et S) peuvent être contrôlés en utilisant le pragma warnings ou les options -w et -W. Si un message peut être contrôlé avec le pragma warnings, la catégorie correspondante de cet avertissement est donnée après la lettre de classification ; par exemple, (W misc) indique un avertissement de type divers. Le pragma warnings est décrit au chapitre 31, Modules de pragmas.

Les avertissements peuvent être capturés plutôt qu'affichés en faisant pointer $SIG{__WARN__} sur une référence de routine qui sera appelée pour chaque message. Vous pouvez également en prendre le contrôle avant qu'une erreur interceptable « meure » en assignant une référence de sous-programme à $SIG{__DIE__}, mais si vous n'appelez pas die à l'intérieur de ce gestionnaire, l'exception sera toujours présente en revenant. En d'autres termes, il n'est pas possible de la « défataliser » par ce biais. Vous devez utiliser eval à cet effet.

Les avertissements par défaut sont toujours activés sauf s'ils sont explicitement désactivés avec le pragma warnings ou l'option -X.

Dans les messages suivants, %s représente une chaîne interpolée qui n'est déterminée qu'au moment de la génération du message. (De même, %d représente un nombre interpolé — pensez aux formats de printf, mais %d signifie ici un nombre dans n'importe quelle base.) Remarquez que certains messages commencent par %s — d'où une certaine difficulté à les classer dans l'ordre alphabétique. Vous pouvez chercher dans ces messages si celui que vous recherchez n'apparaît pas à l'endroit attendu. Les symboles "%-?@ sont triés avant les caractères alphabétiques, alors que [ et \ le sont après.

Si vous êtes persuadé qu'un bogue provient de Perl et non de vous, essayez de le réduire à un cas de test minimal et faites un rapport avec le programme perlbug qui est fourni avec Perl.

N.d.T. Les messages sont indiqués ici en anglais tels qu'ils apparaissent à l'exécution de vos scripts Perl. Toutefois, nous en donnons ici une traduction pour en faciliter la compréhension.

"%s" variable %s masks earlier declaration in same %s

  • (La variable "%s" masque une déclaration précédente dans la même %s) (W misc) Une variable my ou our a été redéclarée dans la portée ou dans l'instruction courante, éliminant effectivement tout accès à l'instance précédente. Il s'agit presque toujours d'une erreur de typographie. Remarquez que la variable déclarée plus tôt existera toujours jusqu'à la fin de la portée ou jusqu'à ce que toutes les fermetures qui s'y réfèrent soient détruites.

"my sub" not yet implemented ("my sub" n'est pas encore implémenté)

  • (F) Les sous-programmes de portée lexicale ne sont pas encore implémentés. N'essayez pas encore cela.

"my" variable %s can't be in a package

  • (La variable "my" %s ne peut pas se trouver dans un paquetage)
  • (F) Les variables de portée lexicale ne se trouvent pas dans un paquetage, et il ne sert donc à rien d'essayer d'en déclarer une, préfixée d'un qualificateur de paquetage. Utilisez local si vous désirez donner une valeur locale à une variable de paquetage.

"no" not allowed in expression ("no" n'est pas autorisé dans une expression)

  • (F) Le mot-clef no est reconnu et exécuté à la compilation et il ne renvoie aucune valeur utile.

"our" variable %s redeclared

  • (La variable "our" %s est redéclarée) (W misc) Il semble que vous avez déjà déclaré la même variable globale auparavant dans la même portée lexicale.

"use" not allowed in expression

  • ("use" n'est pas autorisé dans une expression)
  • (F) Le mot-clef use est reconnu et exécuté à la compilation et il ne renvoie aucune valeur utile.

'!' allowed_only_after types %s

  • ('! n'est autorisé qu'après les types %s)
  • (F) Le '!' n'est autorisé dans pack et unpack qu'après certains types.

'|' and '<' may not both be specified on command line

  • ('|' et '<' ne peuvent pas être spécifiés en même temps sur la ligne de commande)
  • (F) Il s'agit d'une erreur spécifique à VMS. Perl effectue ses propres redirections dans la ligne de commande. Il se trouve que STDIN était un pipe et que vous avez essayé de rediriger STDIN en utilisant <. Un seul flux STDIN par personne, s'il vous plaît.

'|' and '>' may not both be specified on command line

  • ('| et '>' ne peuvent pas être spécifiés en même temps sur la ligne de commande)
  • (F) Il s'agit d'une erreur spécifique à VMS. Perl effectue ses propres redirections dans la ligne de commande et pense que vous avez essayé de rediriger STDOUT à la fois dans un fichier et dans un pipe vers une autre commande. Vous devez choisir l'un ou l'autre, bien que rien ne vous empêche de rediriger dans un pipe vers un programme ou un script Perl qui sépare la sortie standard en deux flux, comme dans :
 
Sélectionnez
open(SORTIE,">$ARGV[0]") or die "Impossible d'écrire dans $ARGV[0] : $!";
while (<STDIN>) {
    print;
    print SORTIE;
} close SORTIE;

/ cannot take a count

  • (/ ne peut pas être lié à un compteur)
  • (F) Vous aviez un canevas pour unpack indiquant une chaîne d'une longueur sujette à un compteur, mais vous avez également spécifié une taille explicite pour cette chaîne.

/ must be followed by a, A ou Z

  • (/ doit être suivi par A, a ou Z)
  • (F) Vous aviez un canevas pour unpack indiquant une chaîne d'une longueur sujette à un compteur ; cette chaîne doit être suivie d'une des lettres a, A ou Z pour indiquer quelle sorte de chaîne doit être dépaquetée.

/ must be followed by a*, A* ou Z*

  • (/ doit être suivi par A*, a* ou Z*)
  • (F) Vous aviez un canevas pour unpack indiquant une chaîne d'une longueur sujette à un compteur. Actuellement, les seules choses dont on peut compter la longueur sont a*, A* ou Z*.

/ must follow a numeric type

  • (/ doit suivre un type numérique)
  • (F) Vous aviez un canevas pour unpack contenant un #, mais celui-ci ne suivait pas l'une des spécifications numériques d'unpack.

% may only be used in unpack

  • (% ne peut être utilisé que dans unpack)
  • (F) Vous ne pouvez pas empaqueter une chaîne avec pack en fournissant une somme de contrôle, car le traitement de cette dernière fait perdre de l'information et vous ne pouvez pas revenir en arrière.

Repeat count in pack overflows

  • (Dépassement du compteur de répétitions dans pack)
  • (F) Vous ne pouvez pas spécifier un compteur de répétitions tellement grand qu'il dépasse la limite pour vos entiers signés.

Repeat count in unpack overflows

  • (Dépassement du compteur de répétitions dans unpack)
  • (F) Vous ne pouvez pas spécifier un compteur de répétitions tellement grand qu'il dépasse la limite pour vos entiers signés.

/%s/ Unrecognized escape \\%c passed through

  • (/%s/ : Rencontre d'une séquence d'échappement \\%c inconnue)
  • (W regexp) Vous avez employé une combinaison avec un caractère antislash qui n'est pas reconnue par Perl. Cette combinaison apparaît dans une variable interpolée ou une expression régulière délimitée par '. Le caractère a été interprété littéralement.

/%s/ Unrecognized escape \\%c in character class passed through

  • (/%s/ : Rencontre d'une séquence d'échappement \\%c inconnue dans une classe de caractères)
  • (W regexp) Vous avez employé une combinaison avec un caractère antislash qui n'est pas reconnue par Perl à l'intérieur d'une classe de caractères. Le caractère a été interprété littéralement.

/%s/ should probably be written as "%s"

  • (/%s/ devrait probablement être écrit "%s")
  • (W syntax) Vous avez employé un motif là où Perl s'attendait à trouver une chaîne, comme dans le premier argument de join. Perl utilisera comme chaîne le résultat vrai ou faux de la correspondance entre le motif et $_, ce qui n'est probablement pas ce que vous aviez en tête.

%s(...) interpreted as function

  • (%s(...) interprété comme une fonction)
  • (W syntax) Vous avez dérogé à la règle qui dit que tout opérateur de liste suivi par des parenthèses devient une fonction prenant comme arguments tous les opérateurs de listes trouvés entre les parenthèses.

%s() called too early to check protoype

  • (%s() appelée trop tôt pour vérifier le prototype)
  • (W prototype) Vous avez appelé une fonction possédant un prototype avant que l'analyseur syntaxique ne voie sa déclaration ou sa définition et Perl ne peut pas vérifier si l'appel se conforme au prototype. Pour obtenir une vérification correcte du prototype, vous devez soit ajouter une déclaration du prototype pour le sous-programme en question plus haut dans le code, soit déplacer la définition du sous-programme avant l'appel. Ou alors, si vous êtes certains d'appeler la fonction correctement, vous pouvez mettre une esperluette devant le nom pour éviter l'avertissement.

%s argument is not a HASH or ARRAY element

  • (L'argument %s n'est un élément ni de HACHAGE, ni de TABLEAU)
  • (F) L'argument de exists doit être un élément de hachage ou de tableau, comme :
 
Sélectionnez
$truc{$bidule}
$ref->{"susie"}[12]

%s argument is not a HASH or ARRAY element or slice

  • (L'argument %s n'est un élément ni de HACHAGE, ni de TABLEAU, ni une tranche)
  • (F) L'argument de delete doit être soit un élément de hachage ou de tableau, comme :
 
Sélectionnez
$truc{$bidule} $ref->{"susie"}[12]

soit une tranche de hachage ou de tableau, comme :

 
Sélectionnez
@truc[$bidule, $machin, $chouette] @{$ref->[12]}{"susie", "queue"}

%s argument is not a subroutine name

  • (L'argument %s n'est pas un nom de sous-programme)
  • (F) L'argument de exists pour exists &sub doit être un nom de sous-programme et non un appel de sous-programme. exists &sub() générera cette erreur.

%s did not return a true value

  • (%s n'a pas renvoyé une valeur vraie)
  • (F) Un fichier requis par require (ou utilisé par use) doit retourner une valeur vraie pour indiquer qu'il s'est compilé correctement et que l'initialisation de son code s'est bien passée. Il est habituel de placer un 1; à la fin d'un tel fichier, bien qu'une quelconque valeur fasse l'affaire.

%s failed--call queue aborted

  • (%s a échoué — file d'appels abandonnée)
  • (F) Une exception non capturée a été levée pendant l'exécution d'un sous-programme CHECK, INIT ou END. Le traitement du reste de la file contenant de telles routines s'est terminé prématurément.

%s found where operator expected

  • (%s trouvé là où l'on attendait un opérateur)
  • (S) L'analyseur lexicographique de Perl sait s'il attend un terme ou un opérateur. S'il voit ce qu'il sait être un terme alors qu'il s'attend à un opérateur, il vous donne ce message d'alerte. Habituellement, cela indique qu'un opérateur ou un séparateur a été omis, comme un point-virgule.

%s had compilation errors

  • (%s a engendré des erreurs de compilation)
  • (F) C'est le message final lorsqu'un perl -c échoue.

%s has too many errors

  • (%s a engendré trop d'erreurs)
  • (F) L'analyseur abandonne son analyse du programme après 10 erreurs. Les messages suivant ne seraient pas sensés.

%s matches null string many times

  • (%s correspond trop de fois à la chaîne vide)
  • (W regexp) Le motif que vous avez spécifié rentrerait dans une boucle infinie si le moteur d'expressions régulières ne contrôlait pas cela.

%s never introduced

  • (%s n'a jamais été introduit)
  • (S internal) Le symbole en question a été déclaré, mais sa portée s'est terminée avant qu'il soit possible de s'en servir.

%s package attribute may clash with future reserved word: %s

  • (L'attribut de paquetage %s risque de rentrer en conflit avec le mot %s réservé pour une utilisation ultérieure)
  • (W reserved) Un nom d'attribut en minuscules géré par un paquetage spécifique a été utilisé. Ce mot pourrait avoir un sens pour Perl un jour, même si ce n'est pas encore le cas. Peut-être devriez-vous employer à la place un nom avec des majuscules et des minuscules mélangées.

%s syntax OK

  • (%s syntaxe OK)
  • (F) Message final lorsqu'un perl -c a réussi.

%s: Command not found

  • (%s : Commande introuvable)
  • (A) Vous avez lancé accidentellement votre script avec csh au lieu de Perl. Vérifiez la ligne avec #! ou lancez vous-même votre script manuellement dans Perl avec perl nom_script.

%s: Expression syntax

  • (%s : Syntaxe d'expression)
  • (A) Vous avez lancé accidentellement votre script avec csh au lieu de Perl. Vérifiez la ligne avec #! ou lancez vous-même votre script manuellement dans Perl avec perl nom_script.

%s: Undefined variable

  • (%s : Variable indéfinie)
  • (A) Vous avez lancé accidentellement votre script avec csh au lieu de Perl. Vérifiez la ligne avec #! ou lancez vous-même votre script manuellement dans Perl avec perl nom_script.

%s: not found

  • (%s : introuvable)
  • (A) Vous avez lancé accidentellement votre script avec le Bourne Shell au lieu de Perl. Vérifiez la ligne avec #! ou lancez vous-même votre script manuellement dans Perl avec perl nom_script.

(in cleanup) %s

  • ((au nettoyage) %s)
  • (W misc) Ce préfixe indique habituellement qu'une méthode DESTROY a levé l'exception indiquée. Puisque les destructeurs sont appelés habituellement par le système à un moment arbitraire durant l'exécution, et bien souvent un grand nombre de fois, cet avertissement n'est affiché qu'une seule fois pour tous les échecs qui sinon auraient causé une répétition du même message. Les échecs des fonctions de rappel (callbacks) définies par l'utilisateur et propagées par l'emploi du flag G_KEEPERR peuvent également entraîner cet avertissement. Voir perlcall(1).

(Missing semicolon on previous line?)

  • (Point-virgule manquant sur la ligne précédente ?)
  • (S) Il s'agit d'une supposition donnée en complément du message « %s found where operator expected ». Pour autant, n'ajoutez pas systématiquement un point-virgule simplement parce que vous avez lu ce message

-P not allowed for setuid/setgid script

  • (-P n'est pas autorisé pour un script setuid/setgid)
  • (F) Le préprocesseur C a voulu ouvrir le script en l'appelant par son nom, ce qui entraîne une situation de concurrence (N.d.T. : race condition) qui casse la sécurité.

-T and -B not implemented on filehandles

  • (-T et -B ne sont pas implémentés sur les handles de fichiers)
  • (F) Perl ne peut utiliser le tampon d'entrée/sortie du handle de fichier quand il ne connaît pas votre type d'entrées/sorties standards. Vous devez utiliser un nom de fichier à la place.

-p destination: %s

  • (Destination de -p : %s)
  • (F) Une erreur est survenue durant l'affichage sur la sortie standard implicite invoquée par l'option de la ligne de commande -p. (Cette sortie est redirigée vers STDOUT à moins que vous ne l'ayez redirigée avec select.)

500 Server error

  • (Erreur de serveur 500) Voir Server error (Erreur de serveur).

?+* follows nothing in regexp

  • (?+* ne suivent rien dans l'expression régulière)
  • (F) Vous avez commencé une expression rationnelle avec un quantifiant. Mettez un antislash devant si vous vouliez l'employer au sens littéral.

@ outside of string

  • (@ à l'extérieur de la chaîne)
  • (F) Vous aviez un canevas empaqueté qui spécifiait une position absolue en dehors de la chaîne à dépaqueter.

<> should be quotes

  • (<> devraient être des apostrophes)
  • (F) Vous avez écrit require <fichier> alors que vous auriez dû écrire require 'fichier'.

\1 better written as $1

  • (Il est préférable d'écrire $1 plutôt que \1)
  • (W syntax) À l'extérieur des motifs, les références arrière (backreferences) existent en tant que variables. L'utilisation d'antislashs du côté droit d'une substitution était autorisée pour nos grands-pères, mais stylistiquement, il mieux vaut adopter la forme des variables attendue par les autres programmeurs Perl. De plus, cela fonctionne mieux s'il y a plus de neuf références arrière.

accept() on closed socket %s

  • (accept() sur une socket fermée %s)
  • (W closed) Vous avez tenté de faire un accept sur une socket fermée. Peut-être avez-vous oublié de vérifier la valeur retournée par l'appel de socket ?

Allocation too large: %lx

  • (Allocation trop grande : %lx)
  • (X) Vous ne pouvez allouer plus de 64K sur une machine MS-DOS.

Applying %s to %s will act on scalar(%s)

  • (Appliquer %s à %s fonctionne avec un scalaire (%s))
  • (W misc) Les opérateurs de recherche de correspondance (//), de substitution (s///) et de translation (tr///) fonctionnent avec des valeurs scalaires. Si vous appliquez l'un d'eux à un tableau ou à un hachage, il convertit ce dernier en une valeur scalaire — la longueur du tableau ou les informations sur le peuplement du hachage — puis travaille sur la valeur scalaire. Ce n'est probablement pas ce que vous vouliez faire.

Arg too short for msgsnd

  • (Argument trop court pour msgsnd)
  • (F) msgsnd nécessite une chaîne au moins aussi longue que sizeof(long).

Ambiguous use of %s resolved as %s

  • (Utilisation ambiguë de %s résolue avec %s)
  • (W ambiguous | S) Vous avez exprimé quelque chose qui n'est pas interprété comme vous le pensiez. Normalement il est assez facile de clarifier la situation en rajoutant une apostrophe manquante, un opérateur, une paire de parenthèses ou une déclaration.

Ambiguous call resolved as CORE::%s(), qualify as such or use &

  • (Appel ambigu résolu avec CORE::%s, qualifiez-le ainsi ou utiliser &)
  • (W ambiguous) Un sous-programme que vous avez déclaré a le même nom qu'un mot-clef de Perl et vous avez utilisé ce nom sans le qualifier pour que l'on puisse distinguer l'un de l'autre. Perl décide d'appeler la fonction interne, car votre sous-programme n'est pas importé. Pour forcer l'interprétation sur l'appel de votre sous-programme, mettez une esperluette avant le nom ou qualifiez votre sous-programme avec son nom de paquetage. Ou alors, vous pouvez importer le sous-programme (ou prétendre le faire avec le pragma use subs).
  • Pour l'interpréter en silence comme l'opérateur Perl, utilisez le préfixe CORE:: sur cet opérateur (ex. CORE::log($x)) ou déclarez le sous-programme en tant que méthode objet.

Args must match #! line

  • (Les arguments doivent correspondre à la ligne #!)
  • (F) L'émulateur setuid nécessite que les arguments invoqués par Perl correspondent avec ceux utilisés sur la ligne #!. Comme certains systèmes imposent un unique argument sur la ligne #!, essayez de combiner les options ; par exemple, changez -w -U en -wU.

Argument "%s" isn't numeric

  1. (L'argument "%s" n'est pas numérique)
  2. (W numeric) La chaîne indiquée est utilisée comme un argument avec un opérateur qui s'attend plutôt à une valeur numérique. Si vous êtes chanceux, le message indique quel opérateur a été si malchanceux.

Array @%s missing the @ in argument %d of %s()

  • (D deprecated) Les versions vraiment antérieures de Perl permettaient d'omettre le @ des tableaux à certains endroits. Ceci est maintenant largement obsolète.

assertion botched: %s

  • (assertion sabotée : %s)
  • (P) Le paquetage malloc fourni avec Perl a subi une erreur interne.

Assertion failed: file "%s"

  • (L'assertion a échoué : fichier "%s")
  • (P) Une assertion générale a échoué. Le fichier en question doit être examiné.

Assignment to both a list and a scalar

  • (Assignement simultané à une liste et à un scalaire)
  • (F) Si vous affectez à un opérateur conditionnel, les deuxième et troisième arguments doivent soit être tous les deux des scalaires, soit tous les deux des listes. Autrement Perl ne connaît pas le contexte à fournir au côté droit.

Attempt to free non-arena SV: 0x%lx

  • (Tentative de libérer un SV hors d'une zone : 0x%lx)
  • (P internal) Tous les objets SV sont supposés être alloués dans une zone qui sera nettoyée à la sortie du script. Un SV a été découvert en dehors d'une de ces zones.

Attempt to free nonexistent shared string

  • (Tentative de libérer une chaîne partagée inexistante)
  • (P internal) Perl maintient une table interne qui compte les références de chaînes pour optimiser le stockage et l'accès aux clefs de hachages et aux autres chaînes. Ce message indique que quelqu'un a essayé de décrémenter le compteur de références d'une chaîne que l'on ne peut plus trouver dans la table.

Attempt to free temp prematurely

  • (Tentative prématurée de libérer une valeur temporaire)
  • (W debugging) Les valeurs à l'agonie (mortalized) sont supposées être libérées par la routine interne free_tmps. Ce message indique que quelque chose d'autre est en train de libérer le SV avant que la routine free_tmps ait une chance de le faire, ce qui signifie que la routine free_tmps libérera un scalaire non référencé au moment où elle tentera de le faire.

Attempt to free unreferenced glob pointers

  • (Tentative de libérer des pointeurs de glob non référencés)
  • (P internal) Le compteur de références a été endommagé en ce qui concerne les alias de symboles.

Attempt to free unreferenced scalar

  • (Tentative de libérer un scalaire non référencé)
  • (W internal) Perl allait décrémenter un compteur de références d'un scalaire pour voir s'il arrivait à 0 et a découvert qu'il était déjà arrivé à 0 auparavant et qu'il se pourrait qu'il ait été libéré et, en fait, qu'il a probablement été libéré. Cela peut indiquer que SvREFCNT_dec a été appelé trop de fois ou que SvREFCNT_inc n'a pas été appelé assez de fois ou encore que le SV a été achevé (mortalized) alors qu'il n'aurait pas dû l'être ou enfin que la mémoire a été corrompue.

Attempt to join self

  • (Tentative de se rejoindre soi-même)
  • (F) Vous avez essayé de rejoindre avec join une tâche (thread) à partir d'elle-même, ce qui est une opération impossible. Vous pourriez rejoindre la mauvaise tâche ou avoir besoin de déplacer le join vers une autre tâche.

Attempt to pack pointer to temporary value

  • (Tentative d'empaqueter un pointeur vers une valeur temporaire)
  • (W pack) Vous avez essayé de passer une valeur temporaire (comme le résultat d'une fonction ou une expression calculée) au canevas p de pack. Cela signifie que le résultat contient un pointeur vers un endroit qui pourrait devenir invalide à tout moment, même avant la fin de l'instruction en cours. Utilisez des valeurs littérales ou globales comme arguments du canevas p de pack pour éviter cet avertissement.

Attempt to use reference as lvalue in substr

  • (Tentative d'utiliser une référence en tant que lvalue dans substr)
  • (W substr) Vous avez soumis une référence utilisée en tant que lvalue comme premier argument de substr, ce qui est vraiment étrange. Peut-être avez-vous oublié de la déréférencer en premier lieu.

Bad arg length for %s, is %d, should be %d

  • (Mauvaise longueur d'argument pour %s, vaut %d, devrait valoir %d)
  • (F) Vous avez passé un tampon de taille incorrecte à msgctl, semctl ou shmctl. En C, les tailles correctes sont respectivement sizeof(struct msqid_ds *), sizeof(struct semid_ds *) et sizeof(struct shmid_ds *).

Bad evalled substitution pattern

  • (Mauvaise évaluation du motif de substitution)
  • (F) Vous avez utilisé l'option /e pour évaluer l'expression de remplacement pour une substitution, mais Perl a trouvé une erreur de syntaxe dans le code à évaluer, très certainement une parenthèse fermante inattendue.

Bad filehandle: %s

  • (Mauvais handle de fichier : %s)
  • (F) Un symbole a été passé à quelque chose qui s'attendait à un handle de fichier, mais le symbole n'a aucun handle de fichier qui lui soit associé. Peut-être avez-vous oublié de faire un open ou dans vous l'avez fait dans un autre paquetage.

Bad free() ignored

  • (Mauvais free() ignoré)
  • (S malloc) Une routine interne a appelé free sur quelque chose qui n'avait jamais été alloué avec malloc dans un premier temps. Ce message est obligatoire, mais peut être désactivé en positionnant la variable d'environnement PERL_BADFREE à 1. Ce message peut être assez fréquent avec DB_file sur les systèmes avec une édition de liens dynamiques en « dur », comme AIX et OS/2. C'est un bogue de Berkeley DB.

Bad hash

  • (Mauvais hachage)
  • (P) Une des routines internes concernant un hachage a passé un pointeur HV nul.

Bad index while coercing array into hash

  • (Mauvais indice lors de la transformation d'un tableau en hachage)
  • (F) La recherche dans le hachage, 0ème élément d'un pseudohachage, a découvert un indice illégal. La valeur des indices doit être supérieure ou égale à 1.

Bad name after %s::

  • (Mauvais nom après %s::)
  • (F) Vous avez commencé un nom de symbole en utilisant un préfixe de paquetage puis vous n'avez pas fini le symbole. En particulier, vous ne pouvez pas faire d'interpolation en dehors des guillemets, ainsi :
 
Sélectionnez
$var = 'ma_var';
$sym = mon_paquetage::$var;

n'est pas identique à :

 
Sélectionnez
$var = 'ma_var'; $sym = "mon_paquetage::$var";

Bad realloc() ignored

  • (Mauvais realloc() ignoré)
  • (S malloc) Une routine interne a appelé realloc sur quelque chose qui n'avait jamais été alloué avec malloc dans un premier temps. Ce message est obligatoire, mais peut être désactivé en positionnant la variable d'environnement PERL_BADFREE à 1.

Bad symbol for array

  • (Mauvais symbole pour un tableau)
  • (P) Une requête interne a demandé à ajouter une entrée de tableau à quelque chose qui n'est pas une entrée dans la table des symboles.

Bad symbol for filehandle

  • (Mauvais symbole pour un handle de fichier)
  • (P) Une requête interne a demandé d'ajouter une entrée de handle de fichier à quelque chose qui n'est pas une entrée dans la table des symboles.

Bad symbol for hash

  • (Mauvais symbole pour un hachage)
  • (P) Une requête interne a demandé à ajouter une entrée de hachage à quelque chose qui n'est pas une entrée dans la table des symboles.

Badly placed ()'s

  • (Parenthèses mal disposées)
  • (A) Vous avez lancé accidentellement votre script avec csh au lieu de Perl. Vérifiez la ligne avec #! ou lancez vous-même votre script dans Perl avec perl nom_script.

Bareword "%s" not allowed while "strict subs" in use

  • (Mot simple "%s" interdit lorsque "strict subs" est activé)
  • (F) Avec « strict subs » activé, un mot simple n'est autorisé que comme identificateur de sous-programme, entre accolades ou à la gauche du symbole =>. Peut-être devriez-vous déclarer au préalable votre sous-programme ?

Bareword "%s" refers to nonexistent package

  • (Le mot simple "%s" se réfère à un paquetage inexistant)
  • (W bareword) Vous avez utilisé un mot simple qualifié de la forme, Truc:: mais le compilateur n'a pas vu d'autre utilisation de cet espace de noms avant cet endroit. Peut-être devriez-vous déclarer au préalable votre paquetage ?

Bareword found in conditional

  • (Mot simple détecté dans une condition)
  • (W bareword) Le compilateur a trouvé un mot simple là où il attendait une condition, ce qui indique souvent qu'un || ou un && a été analysé comme faisant partie du dernier argument de la construction précédente, par exemple :
 
Sélectionnez
open FOO || die;
  • Cela peut également indiquer une constante mal orthographiée qui a été interprétée en tant que mot simple :
 
Sélectionnez
use constant TYPO => 1;
if (TYOP) { print "truc" }
  • Le pragma strict est très utile pour éviter de telles erreurs.

BEGIN failed--compilation aborted

  • (Échec de BEGIN — compilation abandonnée)
  • (F) Une exception non interceptable a été levée pendant l'exécution d'un sous-programme BEGIN. La compilation s'arrête immédiatement et l'on quitte l'interpréteur.

BEGIN not safe after errors--compilation aborted

  • (BEGIN non sécurisé après des erreurs — compilation abandonnée)
  • (F) Perl a trouvé un sous-programme BEGIN (ou une directive use, ce qui implique un BEGIN) après qu'une ou plusieurs erreurs de compilation sont déjà survenues. Comme l'environnement du BEGIN ne peut être garanti (à cause des erreurs) et comme le code qui suit est susceptible de dépendre de son bon fonctionnement, Perl rend la main.

Binary number > 0b11111111111111111111111111111111 non portable

  • (Nombre binaire >0b11111111111111111111111111111111, non portable)
  • (W portable) Le nombre binaire que vous avez spécifié est plus grand que 2**31-1 (4 294 967 295) et n'est donc pas portable entre les systèmes.

bind() on closed socket %s

  • (bind sur une socket fermée %s)
  • (W closed) Vous avez essayé de faire un bind sur une socket fermée. Peut-être avez-vous oublié de vérifier la valeur renvoyée par l'appel de socket ?

Bit vector size > 32 non portable

  • (Taille de vecteur de bits >32, non portable)
  • (W portable) L'utilisation de tailles de vecteurs de bits supérieures à 32 n'est pas portable.

Bizarre copy of %s in %s

  • (Copie étrange de %s dans %s)
  • (P) Perl a détecté une tentative de copie d'une valeur interne qui n'est pas copiable.

Buffer overflow in prime_env_iter: %s

  • (Dépassement du tampon dans prime_env_iter : %s)
  • (W internal) Il s'agit d'un avertissement spécifique à VMS. Pendant que Perl se préparait à parcourir %ENV, il a rencontré un nom logique ou une définition de symbole qui était trop long, il l'a donc tronqué vers la chaîne indiquée.

Callback called exit

  • (La fonction de rappel a appelé exit)
  • (F) Un sous-programme invoqué depuis un paquetage externe via call_sv s'est terminée en appelant exit.

Can't "goto" out of a pseudo block

  • ("goto" impossible vers l'extérieur d'un pseudobloc)
  • (F) Une instruction goto a été exécutée pour quitter ce qui semblerait être un bloc, excepté que ce n'est pas un bloc correct. Ceci se produit habituellement si vous essayez de sauter hors d'un bloc sort ou d'un sous-programme, ce qui n'a pas de sens.

Can't "goto" into the middle of a foreach loop

  • ("goto" impossible vers le milieu d'une boucle foreach)
  • (F) Une instruction goto a été exécutée pour sauter au milieu d'une boucle foreach. Vous ne pouvez y aller depuis cet endroit.

Can't "last" outside a loop block

  • ("last" impossible vers l'extérieur d'un bloc de boucle)
  • (F) Une instruction last a été exécutée pour sortir du bloc courant, excepté ce léger problème qu'il n'existe pas de bloc courant. Remarquez que les blocs if ou else ne comptent pas comme des blocs de boucle, tout comme tout comme les blocs passés à sort, map ou grep. Vous pouvez habituellement doubler les accolades pour obtenir le même effet, car les accolades intérieures seront considérées comme un bloc qui boucle une seule fois.

Can't "next" outside a loop block

  • ("next" impossible vers l'extérieur d'un bloc de boucle)
  • (F) Une instruction next a été exécutée pour recommencer le bloc courant, mais il n'existe pas de bloc courant. Remarquez que les blocs if ou else ne comptent pas comme des blocs de boucle, tout comme les blocs passés à sort, map ou grep. Vous pouvez habituellement doubler les accolades pour obtenir le même effet, car les accolades intérieures seront considérées comme un bloc qui boucle une seule fois.

Can't read CRTL environ

  • (Impossible de lire l'environnement de CRTL)
  • (S) Il s'agit d'un avertissement spécifique à VMS. Perl a essayé de lire un élément de %ENV depuis le tableau d'environnement interne de CRTL et a découvert que le tableau n'existait pas. Vous devez déterminer où CRTL a incorrectement placé son environnement ou définir PERL_ENV_TABLES (voir perlvms(1)) pour que le tableau d'environnement ne soit pas recherché.

Can't "redo" outside a loop block

  • ("redo" impossible vers l'extérieur d'un bloc de boucle)
  • (F) Une instruction redo a été exécutée pour recommencer le bloc courant, mais il n'existe pas de bloc courant. Remarquez que les blocs if ou else ne comptent pas comme des blocs de boucle, tout comme les blocs passés à sort, map ou grep. Vous pouvez habituellement doubler les accolades pour obtenir le même effet, car les accolades intérieures seront considérées comme un bloc qui boucle une seule fois.

Can't bless non-reference value

  • (Impossible de consacrer avec bless une valeur qui ne soit pas une référence)
  • (F) Seules les références en dur peuvent être consacrées avec bless. C'est de cette manière que Perl « applique » l'encapsulation des objets.

Can't break at that line

  • (Impossible de s'arrêter à cette ligne)
  • (S internal) Il s'agit d'un message d'erreur qui n'est affiché que lorsque le programme s'exécute avec le débogueur, indiquant que le numéro de ligne spécifié n'est pas l'emplacement d'une instruction à laquelle on peut s'arrêter.

Can't call method "%s" in empty package "%s"

  • (Impossible d'appeler la méthode "%s" dans le paquetage vide "%s")
  • (F) Vous avez appelé une méthode correctement et vous avez indiqué correctement le paquetage pris en tant que classe, mais ce paquetage n'a rien de défini et n'a pas de méthodes.

Can't call method "%s" on unblessed reference

  • (Impossible d'appeler la méthode "%s" sur une référence non consacrée avec bless)
  • (F) Un appel de méthode doit connaître depuis quel paquetage elle est supposée être lancée. Il trouve habituellement ceci dans la référence de l'objet que vous soumettez, mais vous n'avez pas fourni de référence d'objet dans ce cas. Une référence n'est pas une référence d'objet jusqu'à ce qu'elle ait été consacrée (avec bless).

Can't call method "%s" without a package or object reference

  • (Impossible d'appeler la méthode "%s" dans un paquetage ou une référence d'objet)
  • (F) Vous avez utilisé la syntaxe d'un appel de méthode, mais la place réservée à la référence d'objet ou au nom du paquetage contient une expression qui retourne une valeur définie qui n'est ni une référence d'objet ni un nom de paquetage. Quelque chose comme ceci reproduira l'erreur :
 
Sélectionnez
$MAUVAISE_REF = 42;
traite $MAUVAISE_REF 1,2,3;
$MAUVAISE_REF->traite(1,2,3);

Can't call method "%s" on an undefined value

  • (Impossible d'appeler la méthode "%s" sur une valeur indéfinie)
  • (F) Vous avez utilisé la syntaxe d'un appel de méthode, mais la place réservée à la référence d'objet ou au nom du paquetage contient une une valeur indéfinie. Quelque chose comme ceci reproduira l'erreur :
 
Sélectionnez
$MAUVAISE_REF = undef;
traite $MAUVAISE_REF 1,2,3;
$MAUVAISE_REF->traite(1,2,3);

Can't chdir to %s

  • (chdir impossible vers %s)
  • (F) Vous avez appelé perl -x/truc/bidule, mais /truc/bidule n'est pas un répertoire dans lequel vous pouvez rentrer avec chdir, probablement parce qu'il n'existe pas.

Can't check filesystem of script "%s" for nosuid

  • (Impossible de vérifier le nosuid pour le système de fichier du script "%s")
  • (P) Pour une raison ou pour une autre, vous ne pouvez pas vérifier le nosuid pour le système de fichier du script.

Can't coerce %s to integer in %s

  • (Impossible de convertir %s vers un entier dans %s)
  • (F) On ne peut pas forcer certains types de SV, en particulier les entrées de la table des symboles (typeglobs) à cesser d'être ce qu'ils sont. Donc vous ne pouvez pas faire des choses telles que :
 
Sélectionnez
*truc += 1;

Vous pouvez écrire :

 
Sélectionnez
$truc = *truc; $truc += 1;
  • mais alors $truc ne contient plus de glob.

Can't coerce %s to number in %s

  • (Impossible de convertir %s vers un nombre dans %s)
  • (F) On ne peut pas forcer certains types de SVs, en particulier les entrées de la table des symboles (typeglobs) à cesser d'être ce qu'ils sont.

Can't coerce %s to string in %s

  • (Impossible de convertir %s vers une chaîne dans %s)
  • (F) On ne peut pas forcer certains types de SVs, en particulier les entrées de la table des symboles (typeglobs) à cesser d'être ce qu'ils sont.

Can't coerce array into hash

  • (Impossible de convertir un tableau vers un hachage)
  • (F) Vous avez utilisé un tableau là où un hachage était attendu, mais le tableau n'a pas d'informations sur la manière de passer des clefs aux indices de tableau. Vous ne pouvez faire cela qu'avec les tableaux qui ont une référence de hachage à l'indice 0.

Can't create pipe mailbox

  • (Impossible de créer un pipe de boîte aux lettres)
  • (P) Il s'agit d'une erreur spécifique à VMS. Le processus souffre de quotas dépassés ou d'autres problèmes de plomberie.

Can't declare class for non-scalar %s in "%s"

  • (Impossible de déclarer une classe pour le non-scalaire %s dans "%s")
  • (S) Actuellement, seules les variables scalaires peuvent être déclarées avec un qualificateur de classe spécifique dans une déclaration my ou our. Les sémantiques peuvent être étendues à d'autres types de variables à l'avenir.

Can't declare %s in "%s"

  • (Impossible de déclarer %s dans "%s")
  • (F) Seuls les scalaires, les tableaux et les hachages peuvent être déclarés comme variables my ou our. Ils doivent avoir un identificateur ordinaire comme nom.

Can't do inplace edit on %s: %s

  • (Impossible d'éditer sur place %s)
  • (S inplace) La création du nouveau fichier a échoué à cause de la raison indiquée.

Can't do inplace edit without backup

  • (Impossible d'éditer sur place sans copie de sauvegarde)
  • (F) Vous êtes sur un système comme MS-DOS qui s'embrouille si vous essayez de lire un fichier supprimé (mais toujours ouvert). Vous devez écrire -i.bak, ou quelque chose comme ça.

Can't do inplace edit: %s would not be unique

  • (Impossible d'éditer sur place : %s ne serait pas unique)
  • (S inplace) Votre système de fichier ne supporte pas les noms de fichiers plus longs que 14 caractères et Perl n'a pas pu créer un nom de fichier unique durant l'édition sur place avec l'option -i. Ce fichier a été ignoré.

Can't do inplace edit: %s is not a regular file

  • (Impossible d'éditer sur place : %s n'est pas un fichier ordinaire)
  • (S inplace) Vous avez essayé d'utiliser l'option -i sur un fichier spécial, comme un fichier dans /dev ou une FIFO. Le fichier a été ignoré.

Can't do setegid!

  • (setegid impossible !)
  • (P) L'appel à setegid a échoué pour une raison ou pour une autre dans l'émulateur setuid de suidperl.

Can't do seteuid!

  • (seteuid impossible !)
  • (P) L'émulateur setuid de suidperl a échoué pour une raison ou pour une autre.

Can't do setuid

  • (setuid impossible)
  • (F) Cela veut généralement dire que le perl ordinaire a essayé de faire exec suidperl pour émuler le setuid, mais n'a pas pu faire le exec. Il cherche un nom de la forme sperl5.000 dans le même répertoire que celui où réside l'exécutable perl sous le nom perl5.000, généralement /usr/local/bin sur les machines Unix. Si le fichier s'y trouve, vérifiez les permissions d'exécution. S'il n'est pas là, demandez à votre administrateur système pourquoi.

Can't do waitpid with flags

  • (waitpid impossible avec les drapeaux)
  • (F) Cette machine n'a pas ni waitpid ni wait4, ainsi seul waitpid sans aucun drapeau est émulé.

Can't do {n,m} with n > m

  • (Impossible de faire {n,m} avec n > m)
  • (F) Les minima doivent être inférieurs ou égaux aux maxima. Si vous voulez vraiment que votre expression régulière corresponde 0 fois, faites juste {0}.

Can't emulate -%s on #! line

  • (Impossible d'émuler -%s sur la ligne #!)
  • (F) La ligne #! spécifie une option qui n'a pas de sens à cet endroit. Par exemple, il serait un peu idiot de mettre l'option -x sur cette ligne #!.

Can't exec "%s": %s

  • (exec de "%s" impossible : %s)
  • (W exec) L'appel à system, exec, ou open sur un pipe n'a pu s'exécuter pour la raison indiquée. Les raisons typiques incluent de mauvaises permissions sur le fichier, que le fichier n'a pu être trouvé dans $ENV{PATH}, que l'exécutable en question a été compilé pour une autre architecture ou que la ligne #! pointe vers un interpréteur qui ne peut pas être lancé pour des raisons similaires. (Ou peut-être votre système ne supporte pas du tout #!).

Can't exec %s

  • (exec %s impossible)
  • (F) Perl a essayé d'exécuter le programme indiqué pour vous, car c'est ce qui est spécifié sur la ligne #!. Si ce n'est pas ce que vous vouliez, vous devrez mentionner perl quelque part sur la ligne #!.

Can't execute %s

  • (Impossible d'exécuter %s)
  • (F) Vous avez utilisé l'option -S, mais les copies du script à exécuter trouvées dans le PATH n'ont pas les bonnes permissions.

Can't find %s on PATH, '.' not in PATH

  • (Impossible de trouver %s dans le PATH,"." n'est pas dans le PATH)
  • (F) Vous avez utilisé l'option -S, mais le script à exécuter ne peut être trouvé dans le PATH ou tout au moins avec des permissions incorrectes. Le script existe dans le répertoire courant, mais le PATH l'empêche de se lancer.

Can't find %s on PATH

  • (Impossible de trouver %s dans le PATH)
  • (F) Vous utilisez l'option -S, mais le script à exécuter ne peut être trouvé dans le PATH.

Can't find an opnumber for "%s"

  • (Impossible de trouver un numéro d'opération pour "%s")
  • (F) Une chaîne de la forme CORE::mot a été donnée à, prototype mais il n'existe pas de fonction interne nommée mot.

Can't find label %s

  • (Impossible de trouver l'étiquette %s)
  • (F) Vous avez dit par un goto d'aller à une étiquette qui n'est mentionnée à aucun endroit où il nous est possible d'aller.

Can't find string terminator %s anywhere before EOF

  • (Impossible de trouver la fin de la chaîne %s quelque part avant EOF)
  • (F) Les chaînes de caractères en Perl peuvent s'étirer sur plusieurs lignes. Ce message signifie que vous avez oublié le délimitateur fermant. Comme les parenthèses protégées par des apostrophes comptent pour un niveau, il manque dans l'exemple suivant la parenthèse finale :
 
Sélectionnez
print q(Le caractère '(' commence une nouvelle citation.);
  • Si vous obtenez cette erreur depuis un document « ici-même » (N.d.T. : here document), vous devez avoir mis des espaces blancs non visibles avant ou après la marque de fermeture. Un bon éditeur pour les programmeurs devrait pouvoir vous aider à trouver ces caractères.

Can't fork

  • (fork impossible)
  • (F) Une erreur fatale est survenue en essayant de faire un fork.

Can't get filespec -stale stat buffer?

  • (Impossible d'obtenir la spécification du fichier — tampon stat périmé ?)
  • (S) Il s'agit d'un avertissement spécifique à VMS. Ceci arrive à cause des différences entre les contrôles d'accès sous VMS et sous le modèle Unix qui est celui que Perl présuppose. Sous VMS, les contrôles d'accès sont faits par le nom de fichier, plutôt que par les bits du tampon de stat, ce qui fait que les ACL et les autres protections peuvent être pris en compte. Malheureusement, Perl présuppose que le tampon de stat contient toutes les informations nécessaires et le fournit, à la place de la spécification du fichier, à la fonction de contrôle d'accès. Il va essayer d'obtenir les spécifications du fichier en utilisant le nom du périphérique et le FID présents dans le tampon de stat, mais si vous avez fait ensuite un appel à la fonction stat de CRTL, cela ne fonctionnera pas, car le nom du périphérique est écrasé à chaque appel. Si cet avertissement apparaît, la recherche de nom a échoué et la fonction de contrôle d'accès a rendu la main en retournant une valeur fausse, histoire d'être un peu conservateur. (Remarque : la fonction de contrôle d'accès connaît l'opérateur stat de Perl et les tests de fichiers, vous ne devriez donc jamais voir cet avertissement en réponse à une commande Perl ; il ne se produit que si du code interne prend les tampons de stat à la légère.)

Can't get pipe mailbox device name

  • (Impossible d'obtenir le nom de périphérique d'un pipe de boîte aux lettres)
  • (P) Il s'agit d'une erreur spécifique à VMS. Après avoir créé une boîte aux lettres se comportant comme un pipe, Perl ne peut obtenir son nom pour un usage ultérieur.

Can't get SYSGEN parameter value for MAXBUF

  • (Impossible d'obtenir la valeur du paramètre SYSGEN pour MAXBUF)
  • (P) Il s'agit d'une erreur spécifique à VMS. Perl a demandé à $GETSYI quelle taille vous voulez pour vos tampons de boîtes aux lettres et il n'a pas obtenu de réponse.

Can't goto subroutine outside a subroutine

  • (goto vers un sous-programme impossible à l'extérieur d'un sous-programme)
  • (F) L'appel hautement magique goto SOUS_PROGRAMME ne peut que remplacer l'appel d'une fonction par une autre. Il ne peut en fabriquer une brute de fonderie. En général, vous ne devriez de toute façon l'appeler que depuis une fonction d'AUTOLOAD.

Can't goto subroutine from an eval-string

  • (goto vers un sous-programme impossible depuis une chaîne eval)
  • (F) L'appel goto SOUS_PROGRAMME ne peut être utilisé pour sortir d'une chaîne eval. (Vous pouvez l'utiliser pour sortir d'un, eval BLOC mais ce n'est probablement pas ce que vous voulez.)

Can't ignore signal CHLD, forcing to default

  • (Impossible d'ignorer le signal CHLD, la valeur par défaut est forcée)
  • (W signal) Perl a détecté qu'il avait été lancé avec le signal SIGCHLD (quelquefois appelé SIGCLD) désactivé. Comme la désactivation de ce signal va interférer avec une détermination correcte du statut de sortie des processus fils, Perl a remis le signal à sa valeur par défaut. Cette situation indique généralement que le programme père sous lequel Perl pourrait tourner (exemple : cron) est très peu précautionneux.

Can't localize through a reference

  • (Impossible de rendre locale via une référence)
  • (F) Vous avez écrit quelque chose comme local $$ref, ce que Perl ne sait actuellement pas gérer, car quand il va restaurer l'ancienne valeur de ce vers quoi $ref pointait après que la portée du local est terminée, il ne peut être sûr que $ref soit toujours une référence.

Can't localize lexical variable %s

  • (Impossible de rendre locale la variable %s)
  • (F) Vous avez utilisé local sur une variable qui a déjà été déclarée auparavant comme une variable lexicale à l'aide de my. Ceci n'est pas permis. Si vous voulez rendre locale une variable de paquetage du même nom, qualifiez-la avec le nom du paquetage.

Can't localize pseudo-hash element

  • (Impossible de rendre local un élément de pseudohachage)
  • (F) Vous avez écrit quelque chose comme local $tab->{'clef'}, où $tab est une référence vers un pseudohachage. Cela n'a pas encore été implémenté, mais vous pouvez obtenir un effet similaire en rendant local l'élément du tableau correspondant directement -local $tab->[$tab->[0]{'clef'}].

Can't locate auto/%s.al in @INC

  • (Impossible de trouver auto/%s.al dans @INC)
  • (F) Une fonction (ou une méthode) a été appelée dans un paquetage qui autorise le chargement automatique, mais il n'existe pas de fonction à charger automatiquement. Les causes les plus probables sont une faute de frappe dans le nom de la fonction ou de la méthode ou un échec dans l'AutoSplit du fichier, disons, lors du make install.

Can't locate %s

  • (Impossible de trouver %s)
  • (F) Vous avez écrit de faire un do (ou un require ou un use) sur un fichier qui n'a pu être trouvé. Perl cherche le fichier dans tous les emplacements mentionnés dans @INC, à moins que le nom du fichier ne précise son chemin complet. Peut-être avez-vous besoin de positionner la variable d'environnement PERL5LIB ou PERL5OPT pour indiquer où se trouve la bibliothèque ou il est possible que le script ait besoin d'ajouter le nom de la bibliothèque à @INC. Ou enfin, vous avez peut-être seulement mal épelé le nom du fichier.

Can't locate object method "%s" via package "%s"

  • (Impossible de trouver la méthode objet "%s" via le paquetage %s)
  • (F) Vous avez appelé une méthode correctement et vous avez correctement indiqué un paquetage fonctionnant comme une classe, mais ce paquetage ne définit pas cette méthode-là, ni aucune de ses classes de base.

Can't locate package %s for @%s::ISA

  • (Impossible de trouver le paquetage %s pour @%s::ISA)
  • (W syntax) Le tableau @ISA contient le nom d'un autre paquetage qui semble ne pas exister.

Can't make list assignment to \%ENV on this system

  • (Impossible d'assigner une liste à \%ENV sur ce système)
  • (F) L'affectation d'une liste à %ENV n'est pas supporté sur certains systèmes, notamment VMS.

Can't modify %s in %s

  • (Impossible de modifier %s dans %s)
  • (F) Vous n'êtes pas autorisé à faire d'affectation sur l'élément indiqué, ou à essayer de le changer autrement, comme avec une incrémentation automatique.

Can't modify non-lvalue subroutine call

  • (Impossible de modifier un appel de sous-programme qui ne soit pas une lvalue)
  • (F) Les sous-programmes destinés à être utilisés dans un contexte de lvalue doivent être déclarés en tant que tels.

Can't modify nonexistent substring

  • (Impossible de modifier une sous-chaîne inexistante)
  • (P) La routine interne qui fait l'affectation substr a capturé un NULL.

Can't msgrcv to read-only var

  • (msgrcv d'une var en lecture seule impossible)
  • (F) La cible d'un msgrcv doit être modifiable pour être utilisée comme un tampon de réception.

Can't open %s:%s

  • (Impossible d'ouvrir %s : %s)
  • (S inplace) L'ouverture implicite d'un fichier via le handle de fichier <>, soit implicitement via les options de la ligne de commande -n ou -p, soit explicitement, a échoué à cause de la raison indiquée. Habituellement c'est parce que vous n'avez pas les permissions en lecture sur le fichier que vous avez indiqué sur la ligne de commande.

Can't open bidirectional pipe

  • (Impossible d'ouvrir un pipe bidirectionnel)
  • (W pipe) Vous avez essayé d'écrire open(CMD, "|cmd|"), ce qui n'est pas supporté. Vous pouvez essayer l'un des nombreux modules de la bibliothèque Perl pour faire cela, comme IPC::Open2. Ou alors, dirigez la sortie du pipe dans un fichier en utilisant > et ensuite lisez-le dans un handle de fichier différent.

Can't open error file %s as stderr

  • (Impossible d'ouvrir le fichier d'erreur %s comme stderr)
  • (F) Il s'agit d'une erreur spécifique à VMS. Perl fait ses propres redirections de la ligne de commande et ne peut ouvrir le fichier spécifié après 2> ou 2>> sur la ligne de commande pour y écrire.

Can't open input file %s as stdin

  • (Impossible d'ouvrir le fichier d'entrée %s comme stdin)
  • (F) Il s'agit d'une erreur spécifique à VMS. Perl fait ses propres redirections de la ligne de commande et ne peut ouvrir le fichier spécifié après < sur la ligne de commande pour y lire.

Can't open output file %s as stdout

  • (Impossible d'ouvrir le fichier de sortie %s comme stdout)
  • (F) Il s'agit d'une erreur spécifique à VMS. Perl fait ses propres redirections de la ligne de commande et ne peut ouvrir le fichier spécifié après > ou >> sur la ligne de commande pour y écrire.

Can't open output pipe (name: %s)

  • (Impossible d'ouvrir le pipe de sortie (nom : %s))
  • (P) Il s'agit d'une erreur spécifique à VMS. Perl fait ses propres redirections de la ligne de commande et ne peut ouvrir le pipe dans lequel envoyer les données destinées à STDOUT.

Can't open perl script "%s": %s

  • (Impossible d'ouvrir le script perl "%s" : %s)
  • (F) Le script que vous avez spécifié ne peut être ouvert pour la raison indiquée.

Can't redefine active sort subroutine %s

  • (Impossible de redéfinir le sous-programme de sort actif)
  • (F) Perl optimise la gestion interne des sous-programmes de sort et garde des pointeurs vers ceux-ci. Vous avez essayé de redéfinir un de ces sous-programmes de sort alors qu'il était actuellement actif, ce qui n'est pas permis. Si vous voulez vraiment faire cela, vous devez écrire sort { &fonc } @x au lieu de sort fonc @x.

Can't remove %s:%s, skipping file

  • (Impossible de supprimer %s: %s, fichier passé)
  • (S inplace) Vous avez demandé une édition sur place sans créer un fichier de sauvegarde. Perl a été incapable de supprimer le fichier original pour le remplacer avec celui modifié. Le fichier a été laissé inchangé.

Can't rename %s to %s:%s, skipping file

  • (Impossible de renommer %s en %s : %s, fichier passé)
  • (S inplace) Le renommage effectué par l'option -i a échoué pour une raison ou pour une autre, probablement parce que vous n'avez pas le droit d'écrire dans le répertoire.

Can't reopen input pipe (name: %s) in binary mode

  • (Impossible de rouvrir le pipe d'entrée (nom : %s) en mode binaire)
  • (P) Il s'agit d'une erreur spécifique à VMS. Perl pensait que STDIN était un pipe et a essayé de le rouvrir pour accepter des données binaires. Hélas, cela a échoué.

Can't resolve method "%s" overloading "%s" in paquetage "%s"

  • (Impossible de résoudre la méthode "%s" surchargeant "%s" dans le paquetage "%s")
  • (F|P) Une erreur s'est produite lors de la résolution de la surcharge spécifiée par un nom de méthode (à l'inverse d'une référence de sous-programme) : aucune méthode de ce nom ne peut être appelée via ce paquetage. Si le nom de la méthode est ???, il s'agit d'une erreur interne.

Can't reswap uid and euid

  • (Impossible d'échanger à nouveau l'uid et l'euid)
  • (P) L'appel setreuid a échoué pour une raison ou pour une autre dans l'émulateur setuid de suidperl.

Can't return outside a subroutine

  • (return impossible à l'extérieur d'un sous-programme)
  • (F) L'instruction return a été exécutée dans le fil principal du code, c'est-à-dire là où il n'y a aucun appel de sous-programme dont on peut revenir avec return.

Can't return %s from lvalue subroutine

  • (Impossible de renvoyer %s d'un sous-programme utilisé comme lvalue)
  • (F) Perl a détecté que la valeur renvoyée par un sous-programme utilisé comme lvalue est illégale (constante ou variable temporaire). C'est interdit.

Can't stat script "%s"

  • (stat du script impossible : %s)
  • (P) Pour une raison ou pour une autre, vous ne pouvez faire de fstat sur le script même si vous l'avez déjà ouvert. Bizarre.

Can't swap uid and euid

  • (Impossible d'échanger l'uid et l'euid)
  • (P) L'appel setreuid a échoué pour une raison ou pour une autre dans l'émulateur setuid de suidperl.

Can't take log of %g

  • (Impossible de calculer le log de %g)
  • (F) Pour les nombres réels ordinaires, vous ne pouvez calculer le logarithme d'un nombre négatif ou nul. Il existe toutefois un paquetage Math::Complex livré en standard avec Perl, si c'est vraiment ce que vous voulez faire cela avec les nombres négatifs.

Can't take sqrt of %g

  • (Impossible de calculer la racine carrée de %g)
  • (F) Pour les nombres réels ordinaires, vous ne pouvez calculer la racine carrée d'un nombre négatif. Il existe toutefois le paquetage Math::Complex livré en standard avec Perl, si vous voulez vraiment faire cela.

Can't undef active subroutine

  • (undef du sous-programme actif impossible)
  • (F) Vous ne pouvez rendre indéfinie une fonction qui est actuellement utilisée. Cependant, vous pouvez la redéfinir pendant qu'elle tourne et même faire un undef sur le sous-programme redéfini pendant que l'ancien tourne. Maintenant, c'est à vous de voir.

Can't unshift

  • (unshift impossible)
  • (F) Vous avez essayé de faire un unshift sur un tableau « irréel » qui ne peut accepter cette opération, comme la pile principale de Perl.

Can't upgrade that kind of scalar

  • (Impossible de mettre à niveau ce type de scalaire)
  • (P) La routine interne sv_upgrade a ajouté des « membres » à un SV, ce qui fait qu'il se trouve dans une sorte de SV plus spécialisée. Les différents types les plus élevés de SV sont cependant si spécialisés, qu'ils ne peuvent être convertis entre eux. Ce message indique qu'une telle conversion a été tentée.

Can't upgrade to undef

  • (Impossible de mettre à niveau vers undef)
  • (P) Le SV indéfini représente le niveau zéro de l'évolutivité. L'évolution vers undef indique une erreur dans le code appelant sv_upgrade.

Can't use %%! because Errno.pm is not available

  • (Impossible d'utiliser, %%! car Errno.pm n'est pas disponible)
  • (F) La première fois que le hachage %! est utilisé, Perl charge automatiquement le module Errno. On attend du module Errno qu'il se lie avec tie au hachage %! pour fournir des noms symboliques pour les valeurs des numéros d'erreur de $!.

Can't use "my %s" in sort comparison

  • (Impossible d'utiliser « my %s » dans les comparaisons de sort)
  • (F) Les variables globales $a et $b sont réservées pour les comparaisons de sort. Vous avez mentionné $a ou $b dans la même ligne que les opérateurs <=> ou cmp et la variable avait été déclarée précédemment en tant que variable lexicale. Soit qualifiez la variable de sort avec le nom de paquetage, soit renommez la variable lexicale.

Can't use %s for loop variable

  • (Impossible d'utiliser %s comme variable de boucle)
  • (F) Seule une variable scalaire simple peut être utilisée comme variable de boucle dans un foreach.

Can't use %s ref as %s ref

  • (Impossible d'utiliser la ref %s en tant que ref de %s)
  • (F) Vous avez mélangé vos types de références. Vous devez déréférencer la référence du type nécessaire. Vous pouvez utiliser la fonction ref pour tester le type de la référence, si besoin.

Can't use \%c to mean $%c in expression

  • (Impossible d'utiliser \%c pour signifier $%c dans une expression)
  • (W syntax) Dans une expression ordinaire, l'antislash est un opérateur unaire qui crée une référence vers son argument. L'utilisation d'un antislash pour indiquer une référence arrière vers une sous-chaîne réussissant la correspondance n'est valide qu'à l'intérieur du motif de l'expression régulière. Essayer de faire cela dans un code ordinaire Perl produit une valeur qui s'affiche comme SCALAR(0xdecaf). Utilisez la forme $1 à la place.

Can't use bareword ("%s") as %s ref while "strict refs" in use

  • (Impossible d'utiliser un mot simple ("%s") en tant que ref de %s pendant que "strict refs" est actif)
  • (F) Les références en dur sont les seules autorisées par strict refs. Les références symboliques sont interdites.

Can't use string ("%s") as %s ref while "strict refs" in use

  • (Impossible d'utiliser une chaîne ("%s") en tant que ref de %s pendant que "strict refs" est actif)
  • (F) Les références en dur sont les seules autorisées par strict refs. Les références symboliques sont interdites.

Can't use an undefined value as %s reference

  • (Impossible d'utiliser une valeur indéfinie comme référence de %s)
  • (F) Une valeur utilisée soit comme une référence en dur, soit comme une référence symbolique doit avoir une valeur définie. Cela aide à débloquer certaines erreurs insidieuses.

Can't use global %s in "my"

  • (Impossible d'utiliser la variable globale %s dans "my")
  • (F) Vous avez essayé de déclarer une variable magique en tant que variable lexicale. Cela n'est pas permis, car la variable magique ne peut être liée qu'à un seul endroit (nommé variable globale) et il serait incroyablement confus d'avoir des variables dans votre programme qui ressemblent à des variables magiques, mais qui n'en sont pas.

Can't use subscript on %s

  • (Impossible d'utiliser un indice sur %s)
  • (F) Le compilateur a essayé d'interpréter une expression entre crochets en tant qu'indice. Mais à gauche des crochets, il y avait une expression qui ne ressemblait pas à une référence de tableau, ni à quoi que ce soit que l'on puisse indicer.

Can't weaken a nonreference

  • (Impossible d'affaiblir une non-référence)
  • (F) Vous avez tenté d'affaiblir quelque chose qui n'était pas une référence. Seules les références peuvent être affaiblies.

Can't x= to read-only value

  • (x= impossible sur une valeur en lecture seule)
  • (F) Vous avez essayé de répéter une valeur constante (souvent la valeur indéfinie) avec un opérateur d'affectation, ce qui implique de modifier la valeur elle-même. Peut-être devriez-vous copier la valeur dans une variable temporaire, et répéter cela.

Character class [:%s:] unknown

  • (Classe de caractères [:%s:] inconnue)
  • (F) La classe dans la syntaxe pour une classe de caractères [: :] est inconnue.

Character class syntax [%s] belongs inside character classes

  • (La syntaxe [%s] pour une classe de caractères appartient aux classes de caractères)
  • (W unsafe) Les constructions de classes de caractères [: :], [= =] et [. .] se rangent dans les classes de caractères, par exemple : /[012[:alpha:]345]/. Remarquez que les constructions [= =] et [. .] ne sont pas implémentées actuellement ; ce sont juste des places réservées pour de futures extensions.

Character class syntax [. .] is reserved for future extensions

  • (Syntaxe [. .] pour une classe de caractère réservée pour de futures extensions)
  • (W regexp) À l'intérieur des classes de caractères dans les expressions régulières ([]), la syntaxe commençant par [. et se terminant par .] est réservée pour de futures extensions. Si vous avez besoin de représenter de telles séquences de caractères à l'intérieur d'une classe de caractères dans une expression régulière, protégez simplement les crochets avec un antislash : \[. et .\].

Character class syntax [= =] is reserved for future extensions

  • (Syntaxe [= =] pour une classe de caractère réservée pour de futures extensions)
  • (W regexp) À l'intérieur des classes de caractères dans les expressions régulières ([]), la syntaxe commençant par [= et se terminant par =] est réservée pour de futures extensions. Si vous avez besoin de représenter de telles séquences de caractères à l'intérieur d'une classe de caractères dans une expression régulière, protégez simplement les crochets avec un antislash : \[. et .\].

chmod() mode argument is missing initial 0

  • (Il manque le 0 au début de l'argument représentant le mode de chmod())
  • (W chmod) Un utilisateur novice aura tendance à écrire :

     
    Sélectionnez
    chmod 777, $fichier
  • en ne réalisant pas que 777 sera interprété comme un nombre décimal, équivalent à 01411. Les constantes octales sont introduites en les faisant débuter par un 0 en Perl, tout comme en C.

Close on unopened file <%s>

  • (Ferme un fichier non ouvert <%s>)
  • (W) Vous avez essayé de fermer un descripteur de fichier qui n'avait jamais été ouvert.

Compilation failed in require

  • (Échec de la compilation dans require)
  • (F) Perl n'a pas pu compiler le fichier spécifié dans une instruction require. Perl utilise ce message générique lorsqu'aucune des erreurs rencontrées n'est assez grave pour arrêter la compilation immédiatement.

Complex regular subexpression recursion limit (%d) exceeded

  • (Limite de récursion pour les expressions régulières complexes (%d) atteinte)
  • (W regexp) Le moteur d'expressions régulières utilise la récursion dans les situations complexes où les retours arrières sont nécessaires. La profondeur de la récursion est limitée à 32 766, ou peut-être moins sur les architectures où la pile ne peut croître arbitrairement. (Les situations « simples » et « moyennes » peuvent être gérées sans récursion et ne sont pas sujettes à une limite.) Essayez de raccourcir la chaîne examinée, faites des boucles dans le code Perl (exemple : avec while) plutôt qu'avec le moteur d'expressions régulières ou réécrivez l'expression régulière pour qu'elle soit plus simple ou qu'elle contienne moins de retours arrière.

connect() on closed socket %s

  • (connect() sur une socket fermée %s)
  • (W closed) Vous avez essayé de faire un connect sur une socket fermée. Peut-être avez-vous oublié de vérifier la valeur retournée par l'appel de socket ?

Constant is not %s reference

  • (La constante n'est pas une référence de %s)
  • (F) Une valeur constante (déclarée peut-être en utilisant le pragma use constant) est déréférencée, mais équivaut à une référence d'un mauvais type. Le message indique le type de référence qui était attendu. Ceci indique habituellement une erreur de syntaxe en déréférençant la valeur constante.

Constant subroutine %s redefined

  • (Sous-programme constant %s redéfini)
  • (S|W redefine) Vous avez redéfini un sous-programme qui a été désigné auparavant comme étant en ligne (inlining).

Constant subroutine %s undefined

  • (Sous-programme constant %s indéfini)
  • (W misc) Vous avez rendu indéfini un sous-programme qui a été désigné auparavant comme étant en ligne (inlining).

constant(%s): %s

  • (constant(%s) : %s)
  • (F) L'analyseur syntaxique a trouvé des incohérences soit en tentant de définir une constante surchargée, soit en essayant de trouver le nom de caractère spécifié dans la séquence d'échappement \N{...}. Peut-être avez-vous oublié de charger les pragmas correspondants overload ou charnames.

Copy method did not return a reference

  • (La méthode de copie n'a pas renvoyé de référence)
  • (F) La méthode qui surcharge = est boguée.

CORE::%s is not a keyword

  • (CORE::%s n'est pas un mot clef)
  • (F) L'espace de noms CORE:: est réservé pour les mots clefs de Perl.

Corrupt malloc ptr 0x%lx at 0x%lx

  • (Pointeur de malloc 0x%lx corrompu en 0x%lx)
  • (P) Le paquetage malloc distribué avec Perl a eu une erreur interne.

corrupted regexp pointers

  • (Pointeurs d'expressions régulières corrompus)
  • (P) Le moteur d'expressions régulières est devenu confus parce que le compilateur d'expressions régulières lui a donné.

corrupted regexp program

  • (Programme d'expressions régulières corrompu)
  • (P) On a passé au moteur d'expressions régulières un programme d'expression régulière sans nombre magique valide.

Deep recursion on subroutine "%s"

  • (Récursion profonde pour le sous-programme "%s")
  • (W recursion) Ce sous-programme s'est appelé lui-même (directement ou indirectement) 100 fois de plus qu'il n'est revenu. Ceci indique probablement une récursion infinie, à moins que vous n'écriviez un étrange programme de benchmark, auquel cas cela indique quelque chose d'autre.

defined(@array) is deprecated

  • (defined(@tableau) est déprécié)
  • (D deprecated) defined n'est habituellement pas très utile sur les tableaux, car il teste la présence d'une valeur scalaire indéfinie. Si vous voulez voir si le tableau est vide, vous n'avez qu'à utiliser if (@tableau) { # pas vide }.

defined(%hash) is deprecated

  • (defined(%hachage) est déprécié)
  • (D deprecated) defined n'est habituellement pas très utile sur les hachages, car il teste la présence d'une valeur scalaire indéfinie. Si vous voulez voir si le hachage est vide, vous n'avez qu'à utiliser if (%hachage) { # pas vide }.

Delimiter for here document is too long

  • (Le délimiteur pour le document « ici-même » est trop long)
  • (F) Dans une construction de document « ici-même », comme <<TRUC, l'étiquette TRUC est trop longue pour que Perl puisse la gérer. Il faut que vous soyez sérieusement tordu pour écrire un code qui déclenche cette erreur.

Did not produce a valid header

  • (N'a pas produit un en-tête valide)
  • Voir Server error.

(Did you mean &%s instead?)

  • (Avez-vous plutôt voulu dire &%s ?)
  • (W) Vous avez probablement fait référence à un sous-programme importé &TRUC en faisant $TRUC ou quelque chose du genre.

(Did you mean "local" instead of "our"?)

  • (Avez-vous voulu dire "local" plutôt que "our" ?)
  • (W misc) Souvenez-vous que our ne rend pas locale la variable déclarée comme globale. Vous l'avez redéclarée dans la même portée lexicale, ce qui semble superflu.

(Did you mean $ or @ instead of %?)

  • (Avez-vous voulu dire $ ou @ plutôt que % ?)
  • (W) Vous avez probablement écrit %hachage{$clef} alors que vous pensiez $hachage{$clef} ou @hachage{@clefs}. D'un autre côté, peut-être avez-vous juste voulu dire %hachage et vous vous êtes laissé emporter.

Died

  • (Mort)
  • (F) Vous avez appelé à die une chaîne vide (l'équivalent de die "") ou vous l'avez appelé sans arguments et à la fois $@ et $_ étaient vides.

(Do you need to predeclare %s?)

  • (Avez-vous besoin de prédéclarer %s)
  • (S) Il s'agit d'une supposition donnée en complément du message « %s found where operator expected ». Cela veut souvent dire qu'un nom de sous-programme ou de module a été référencé alors qu'il n'a pas encore été défini. C'est peut être un problème d'ordre dans votre fichier ou parce qu'il manque une instruction sub, package, require ou use. Si vous référencez quelque chose qui n'est pas encore défini, en fait vous n'avez pas à définir le sous-programme ou le paquetage avant cet endroit. Vous pouvez utiliser un sub truc; ou un package TRUC; vide pour entrer une déclaration « par avance ».

Document contains no data

  • (Le document ne contient pas de données)
  • Voir Server error.

Don't know how to handle magic of type '%s'

  • (Ne sait pas comment gérer la magie du type '%s')
  • (P) On a jeté un sort sur la gestion interne des variables magiques.

do_study: out of memory

  • (do_study : débordement de mémoire)
  • (P) Ce message aurait plutôt dû être capturé par safemalloc.

Duplicate free() ignored

  • (Duplication de free() ignorée)
  • (S malloc) Une routine interne a appelé free sur quelque chose qui a déjà été libéré.

elseif should be elsif

  • (elseif devrait être elsif)
  • (S) Il n'y a pas de mot-clef « elseif » en Perl, car Larry pense que c'est très laid. Votre code sera interprété comme une tentative d'appel à la méthode nommée elseif pour la classe renvoyée par le bloc qui suit. Ce n'est sûrement pas ce que vous voulez.

entering effective %s failed

  • (L'entrée dans %s effectif a échoué)
  • (F) Alors que le pragma use filetest était actif, l'échange entre les UID ou les GID réels et effectifs a échoué.

Error converting file specification %s

  • (Erreur en convertissant la spécification de fichier %s)
  • (F) Il s'agit d'une erreur spécifique à VMS. Comme Perl doit gérer des spécifications de fichiers dans les syntaxes VMS ou Unix, il convertit celles-ci dans un format unique lorsqu'il doit les traiter directement. Soit vous avez passé des spécifications de fichier invalides, soit vous avez trouvé un cas que les routines de conversion ne gèrent pas. Zut !

%s: Eval-group in insecure regular expression

  • (%s : Groupe eval dans une expression régulière non sécurisée)
  • (F) Perl a détecté une donnée marquée en essayant de compiler une expression régulière qui contient l'assertion de longueur zéro (?{ ... }) , ce qui n'est pas sécurisé.

%s: Eval-group not allowed, use re 'eval'

  • (%s : Groupe eval interdit, utilisez use re 'eval')
  • (F) Une expression régulière contenait l'assertion de longueur nulle (?{ ... }), mais cette construction est seulement permise quand le pragma use re 'eval' est actif.

%s: Eval-group not allowed at run time

  • (%s : Groupe eval interdit à l'exécution)
  • (F) Perl a essayé de compiler une expression régulière contenant l'assertion de longueur nulle (?{ ... }) à l'exécution, comme il le ferait si le motif contenait des valeurs interpolées. Comme c'est un risque de sécurité, cela n'est pas permis. Si vous insistez, vous pouvez toujours le faire en construisant explicitement votre motif depuis une chaîne interpolée à l'exécution et l'utiliser dans un eval.

Excessively long <> operator

  • (Opérateur <> excessivement long)
  • (F) Le contenu d'un opérateur <> ne doit pas excéder la taille maximum d'un identificateur Perl. Si vous essayez seulement d'obtenir les extensions d'une longue liste de fichiers, essayez d'utiliser l'opérateur glob ou mettez les noms de fichiers dans une variable et faites un glob dessus.

Execution of %s aborted due to compilation errors

  • (Exécution de %s abandonnée à cause d'erreurs de compilation)
  • (F) Le message de résumé final lorsqu'une compilation Perl échoue.

Exiting eval via %s

  • (Sortie d'un eval via %s)
  • (W exiting) Vous êtes sorti d'un eval d'une façon non conventionnelle, comme un goto ou une instruction de contrôle de boucle.

Exiting format via %s

  • (Sortie d'un format via %s)
  • (W exiting) Vous êtes sorti d'un format d'une façon non conventionnelle, comme un goto ou une instruction de contrôle de boucle.

Exiting pseudoblock via %s

  • (Sortie d'un pseudobloc via %s)
  • (W exiting) Vous êtes sorti d'une construction tout à fait spéciale de bloc (comme un bloc ou un sous-programme de sort) d'une façon non conventionnelle, comme un goto, ou une instruction de contrôle de boucle.

Exiting subroutine via %s

  • (Sortie d'un sous-programme via %s)
  • (W exiting) Vous êtes sorti d'un sous-programme d'une façon non conventionnelle, comme un goto ou une instruction de contrôle de boucle.

Exiting substitution via %s

  • (Sortie d'une substitution via %s)
  • (W exiting) Vous êtes sorti d'une substitution d'une façon non conventionnelle, comme un goto ou une instruction de contrôle de boucle.

Explicit blessing to '' (assuming package main)

  • (Consécration par bless explicite vers '' (paquetage principal main adopté))
  • (W misc) Vous avez consacré par bless une référence à une chaîne de longueur nulle. Cela a pour effet de consacrer la référence dans le paquetage principal main. Ce n'est pas habituellement ce que vous voulez. Pensez à fournir un paquetage cible par défaut, comme dans bless($ref, $p || 'Mon_Paquetage');.

false [] range "%s" in regexp

  • (Faux intervalle [] "%s" dans l'expression régulière)
  • (W regexp) Un intervalle de classe de caractères doit débuter et finir par un caractère littéral et non par une autre classe de caractères comme \d ou [:alpha:]. Le dans votre faux intervalle est interprété comme un - littéral. Pensez à protéger le comme cela : \-.

Fatal VMS error at %s, line %d

  • (Erreur VMS fatale dans %s, ligne %d)
  • (P) Il s'agit d'une erreur spécifique à VMS. Il s'est passé quelque chose de fâcheux dans un service du système VMS ou dans une routine CRTL ; le statut de sortie de Perl devrait fournir plus de détails. Le nom de fichier dans at %s et le numéro de ligne dans line%d vous indiquent quelle section du code source Perl a été affectée.

fcntl is not implemented

  • (fcntl non implémenté)
  • (F) Votre machine n'implémente apparemment pas fcntl. Qu'est-ce que c'est que ça, un PDP-11 ou quelque chose de similaire ?

Filehandle %s never opened

  • (Handle de fichier %s jamais ouvert)
  • (W unopened) Une opération d'entrée/sortie a été tentée sur un handle de fichier qui n'a jamais été initialisé. Vous devez faire un appel à open ou à socket ou appeler un constructeur du module FileHandle.

Filehandle %s opened only for input

  • (Handle de fichier %s ouvert seulement pour les entrées)
  • (W io) Vous avez tenté d'écrire dans un handle de fichier ouvert en lecture seule. Si vous vouliez que ce soit un handle de fichier ouvert en lecture-écriture, vous deviez l'ouvrir avec +<, +> ou +>> au lieu de < ou rien du tout. Si vous désiriez uniquement écrire dans le fichier, utilisez > ou >>.

Filehandle %s opened only for output

  • (Handle de fichier %s ouvert seulement pour les sorties)
  • (W io) Vous avez tenté de lire dans un handle de fichier ouvert en écriture seule. Si vous vouliez que ce soit un handle de fichier ouvert en lecture-écriture, vous deviez l'ouvrir avec +<, +> ou +>> au lieu de < ou rien du tout. Si vous désiriez uniquement lire dans le fichier, utilisez <.

Final $ should be \$ or $name

  • ($ final devrait être \$ ou $nom)
  • (F) Vous devez maintenant décider si le $ final dans une chaîne devait être interprété comme le signe dollar littéral ou s'il était là pour introduire un nom de variable s'avérant manquer. Vous devez donc ajouter soit l'antislash, soit le nom.

Final @ should be \@ or @name

  • (@ final devrait être \@ ou @nom)
  • (F) Vous devez maintenant décider si le @ final dans une chaîne devait être interprété comme le signe arobase littéral ou s'il était là pour introduire un nom de variable s'avérant manquer. Vous devez donc ajouter soit l'antislash, soit le nom.

flock() on close filehandle %s

  • (flock() sur un handle de fichier fermé %s)
  • (W closed) Le handle de fichier sur lequel vous avez essayé de faire flock a été lui-même fermé quelque temps auparavant. Vérifiez le flux logique de votre programme. flock agit sur des handles de fichiers. Avez-vous tenté d'appeler flock sur un handle de répertoire du même nom ?

Format %s redefined

  • (Format %s redéfini)
  • (W redefine) Vous avez redéfini un format. Pour supprimer cet avertissement, écrivez
 
Sélectionnez
{
    no warnings;
    eval "format NAME =...";
}

Format not terminated

  • (Format inachevé)
  • (F) Un format doit être terminé par une ligne contenant uniquement un point. Perl est arrivé en fin de fichier sans trouver une telle ligne.

Found = in conditional, should be ==

  • (= trouvé dans une condition, devrait être ==)
  • (W syntax) Vous avez écrit :
 
Sélectionnez
if ($truc = 123)
  • alors que vous vouliez dire :

     
    Sélectionnez
    if ($truc == 123)
  • (ou quelque chose de similaire).

gdbm store returned %d, errno %d, key "%s"

  • (Le stockage gdbm a renvoyé %d, numéro d'erreur %d, clef "%s")
  • (S) Un avertissement de l'extension GDBM_File indique qu'un stockage a échoué.

gethostent not implemented

  • (gethostent non implémenté)
  • (F) Votre bibliothèque C n'implémente apparemment pas gethostent, probablement parce que si elle le faisait, elle se sentirait moralement obligée de renvoyer chaque nom d'hôte existant sur Internet.

get%sname() on closed socket %s

  • (get%sname() sur une socket fermée %s)
  • (W closed) Vous avez essayé d'obtenir une socket ou une socket parente d'une socket fermée. Peut-être avez-vous oublié de vérifier la valeur renvoyée par l'appel socket ?

getpwnam returned invalid UIC %#o for user "%s"

  • (getpwname a renvoyé l'UIC %#0 invalide pour l'utilisateur "%s")
  • (S) Il s'agit d'un avertissement spécifique à VMS. L'appel à sys$getuai, sous-jacent de l'opérateur getpwnam, a retourné une UIC invalide.

glob failed (%s)

  • (Échec du glob)
  • (W glob) Quelque chose s'est mal passé avec le(s) programme(s) externe(s) utilisé(s) par glob et <*.c>. Habituellement, cela signifie que vous avez fourni un motif de glob qui a entraîné l'échec du programme externe qui s'est terminé avec un statut différent de zéro. Si le message indique que la sortie anormale a engendré une copie du cœur du programme (core dump), ceci peut également vouloir dire que votre csh (C shell) est corrompu. Si c'est le cas, vous devriez changer toutes les variables se rapportant à csh dans config.sh. Si vous utilisez tcsh, changez les variables qui s'y réfèrent comme si c'était csh. (ex. full_csh='/usr/bin/tcsh') ; sinon, videz-les toutes (sauf d_csh qui devrait valoir 'undef') pour que Perl croit qu'il manque csh. Dans tous les cas, une fois config.sh mis à jour, lancez ./Configure -S et reconstruisez Perl.

Glob not terminated

  • (Glob non terminé)
  • (F) L'analyseur lexical a vu un signe inférieur à un endroit où il s'attendait à trouver un terme, il recherche donc le signe supérieur correspondant et ne le trouve pas. Il y a des chances que vous ayez oublié des parenthèses nécessaires auparavant dans la ligne et que vous avez réellement voulu dire le symbole <.

Global symbol "%s" requires explicit package name

  • (Le symbole global "%s" exige un nom de paquetage explicite)
  • (F) Vous avez écrit use strict vars, ce qui indique que toutes les variables doivent soit avoir une portée lexicale (en utilisant my), soit être déclarés au préalable en utilisant our, soit être explicitement qualifiées pour dire à quel paquetage la variable globale appartient (en utilisant ::).

Got an error from DosAllocMem

  • (Erreur rencontrée depuis DosAllocMem)
  • (P) Il s'agit d'une erreur spécifique à OS/2. Le plus probable est que vous employez une version obsolète de Perl, cette erreur ne devrait donc jamais se produire de toute façon.

goto must have label

  • (goto doit avoir une étiquette)
  • (F) Au contraire de next et de last, vous n'êtes pas autorisés à faire un goto vers une destination non spécifiée.

Had to create %s unexpectedly

  • (A dû créer %s de manière inattendue)
  • (S internal) Une routine a demandé un symbole dans une table des symboles qui aurait dû déjà exister, mais pour une raison ou pour une autre ce n'était pas le cas elle a été crée en urgence pour éviter une copie du cœur du programme (core dump).

Hash %%s missing the % in argument %d of %s()

  • (Il manque le % du hachage %%s dans l'argument %d de %s ())
  • (D deprecated) Seules les versions de Perl vraiment anciennes vous permettaient d'omettre le % dans les noms de hachage à certains endroits. C'est maintenant largement obsolète.

Hexadecimal number > 0xffffffff non-portable

  • (Nombre hexadécimal > 0xffffffff, non portable)
  • (W portable) Le nombre hexadécimal que vous avez spécifié est plus grand que 2**32-1 (4 294 967 295) et n'est donc pas portable d'un système à l'autre.

Identifier too long

  • (Identificateur trop long)
  • (F) Perl limite la taille des identificateurs (noms des variables, fonctions, etc.) à 250 caractères environ pour les noms simples et un peu plus pour les noms composés (comme $A::B). Vous avez dépassé les limites de Perl. Les futures versions de Perl seront susceptibles d'éliminer ces limitations arbitraires.

Ill-formed CRTL environ value "%s"

  • (Valeur d'environnement de CRTL "%s" mal formée)
  • (W internal) Il s'agit d'un avertissement spécifique à VMS. Perl a essayé de lire le tableau d'environnement interne de CRTL et a rencontré un élément sans le séparateur = utilisé pour séparer les clefs des valeurs. L'élément est ignoré.

Ill-formed message in prime_env_iter: |%s|

  • (Message mal formé dans prime_env_iter : |%s|)
  • (W internal) Il s'agit d'un avertissement spécifique à VMS. Perl a essayé de lire un nom logique ou une définition de symbole CLI en se préparant à parcourir %ENV et il n'a pas vu le séparateur attendu entre les clefs et les valeurs, la ligne a donc été ignorée.

Illegal character %s (carriage return)

  • (Caractère illégal %s (retour chariot))
  • (F) D'ordinaire, Perl traite les retours chariots dans le texte du programme au même titre que n'importe quel autre caractère d'espacement, ce qui signifie que vous ne devriez jamais voir cette erreur lorsque Perl a été construit en utilisant les options standards. Pour une raison ou pour une autre, votre version de Perl semble avoir été construite sans ce support. Parlez-en à votre administrateur Perl.

Illegal division by zero

  • (Division par zéro illégale)
  • (F) Vous avez essayé de diviser un nombre par 0. Soit quelque chose clochait dans votre logique, soit vous devez placer une condition pour vous préserver de cette entrée dénuée de sens.

Illegal modulus zero

  • (Modulo zéro illégal)
  • (F) Vous avez essayé de diviser un nombre par 0 pour obtenir le reste. La plupart des nombres ne peuvent faire cela gentiment.

Illegal binary digit

  • (Chiffre binaire illégal)
  • (F) Vous avez utilisé un chiffre autre que 0 ou 1 dans un nombre binaire.

Illegal octal digit

  • (Chiffre octal illégal)
  • (F) Vous avez utilisé un 8 ou un 9 dans un nombre octal.

Illegal binary digit %s ignored

  • (Chiffre binaire illégal %s, ignoré)
  • (W digit) Vous avez essayé d'utiliser un chiffre autre que 0 ou 1 dans un nombre binaire. L'interprétation du nombre binaire s'est arrêtée avant le chiffre en cause.

Illegal octal digit %s ignored

  • (Chiffre octal illégal %s, ignoré)
  • (W digit) Vous avez peut-être essayé d'utiliser un 8 ou un 9 dans un nombre octal. L'interprétation du nombre octal s'est arrêtée avant le 8 ou le 9.

Illegal hexadecimal digit %s ignored

  • (Chiffre hexadécimal illégal %s, ignoré)
  • (W digit) Vous avez essayé d'utiliser un caractère autre qui n'est ni entre 0 et 9, ni entre A et F, ni entre a et f dans un nombre hexadécimal. L'interprétation du nombre hexadécimal s'est arrêtée avant le caractère illégal.

Illegal number of bits in vec

  • (Nombre de bits illégal dans vec)
  • (F) Le nombre de bits dans vec (le troisième argument) doit être une puissance de deux de 1 à 32 (ou 64 si votre plate-forme le supporte).

Illegal switch in PERL5OPT: %s

  • (Option illégale dans PERL5OPT : %s)
  • (X) La variable d'environnement PERL5OPT ne peut être utilisée que pour positionner les options suivantes : -[DIMUdmw].

In string, @%s now must be written as \@%s

  • (Dans une chaîne, @%s doit maintenant s'écrire \@%s)
  • (F) Perl essayait auparavant de deviner si vous vouliez un tableau interpolé ou un @ littéral. Il faisait ceci lorsque la chaîne était utilisée la première fois pendant l'exécution. Les chaînes sont maintenant analysées à la compilation et les instances ambiguës de @ doivent être éclaircies, soit en préfixant par un antislash pour indiquer qu'il s'agit d'un littéral, soit en déclarant (ou en utilisant) le tableau dans le programme avant la chaîne (lexicalement). (Un jour un @ sans antislash sera simplement interprété comme une interpolation d'un tableau.)

Insecure dependency in %s

  • (Dépendance non sécurisée dans %s)
  • (F) Vous avez essayé de faire quelque chose que le mécanisme de marquage des variables n'a pas apprécié. Ce mécanisme de marquage est activé quand vous exécutez un script setuid ou setgid, ou lorsque vous spécifiez -T pour l'activer explicitement. Le mécanisme de marquage étiquette toutes les données dérivées directement ou indirectement de l'utilisateur, qui est considéré indigne de votre confiance. Si l'une de ces données est utilisée dans une opération « dangereuse », vous obtenez cette erreur.

Insecure directory in %s

  • (Répertoire non sécurisé dans %s)
  • (F) Vous ne pouvez utilisez system, exec ou un pipe ouvert vers un script setuid ou setgid si $ENV{PATH} contient un répertoire qui a les droits en écriture pour tout le monde.

Insecure $ENV{%s} while running %s

  • ($ENV{%s} non sécurisé alors que %s est en train de tourner)
  • (F) Vous ne pouvez utiliser system, exec ou un pipe ouvert vers un script setuid ou setgid si $ENV{PATH}, $ENV{IFS}, $ENV{CDPATH}, $ENV{ENV} ou $ENV{BASH_ENV} sont dérivés de données fournies (ou potentiellement fournies) par l'utilisateur. Le script doit positionner le chemin à une valeur connue, en utilisant une donnée digne de confiance.

Integer overflow in %s number

  • (Dépassement d'entier dans le nombre %s)
  • (W overflow) Le nombre hexadécimal, octal ou binaire que vous avez spécifié soit comme littéral, soit comme argument de hex ou oct est trop grand pour votre architecture. Sur les machines 32-bits, les plus grands nombres hexadécimaux, octaux ou binaires représentables sans dépassement sont 0xFFFFFFFF, 037777777777 et 0b11111111111111111111111111111111, respectivement. Remarquez que Perl élève de manière transparente tous les nombres vers une représentation interne en virgule flottante — sujette à des erreurs de perte de précision dans les opérations ultérieures.

Internal inconsistency in tracking vforks

  • (Incohérence interne dans la recherche des vfork s)
  • (S) Il s'agit d'un avertissement spécifique à VMS. Perl garde une trace du nombre de fois où vous avez appelé fork et exec, pour déterminer si l'appel courant à exec devrait affecter le script en cours ou un sous-processus (Voir « exec LIST » dans perlvms(1)). De toute façon, ce compte est devenu perturbé, Perl fait donc une supposition et traite ce exec comme une requête pour terminer le script Perl et exécuter la commande spécifiée.

internal disaster in regexp

  • (désastre interne dans une expression régulière)
  • (P) Quelque chose s'est très mal passé dans l'analyseur d'expressions régulières.

internal urp in regexp at /%s/

  • (gloups interne dans une expression régulière)
  • (P) Quelque chose a très mal tourné dans l'analyseur d'expressions régulières.

Invalid %s attribute: %s

  • (Attribut %s invalide : %s)
  • (F) L'attribut indiqué pour un sous-programme ou une variable n'a pas été reconnu par Perl ou par un gestionnaire fourni par l'utilisateur.

Invalid %s attributes: %s

  • (Attributs %s invalides : %s)
  • (F) Les attributs indiqués pour un sous-programme ou une variable n'ont pas été reconnus par Perl ou par un gestionnaire fourni par l'utilisateur.

invalid [] range "%s" in regexp

  • (Intervalle [] "%s" invalide dans l'expression régulière)
  • (F) L'intervalle spécifié dans une classe de caractères a un caractère de début supérieur au caractère de fin.

Invalid conversion in %s:"%s"

  • (Conversion invalide dans %s : "%s")
  • (W printf) Perl ne comprend pas le format de conversion donné.

Invalid separator character %s in attribute list

  • (Caractère de séparation %s invalide dans la liste d'attributs)
  • (F) Quelque chose d'autre qu'un deux-points ou qu'un espacement a été détecté entre les éléments d'une liste d'attributs. Si l'attribut précédent avait une liste de paramètres entre parenthèses, peut-être que cette liste s'est terminée trop tôt.

Invalid type in pack: '%s'

  • (Type invalide dans pack : '%s')
  • (F) Le caractère donné n'est pas un type d'empaquetage valide.
  • (W pack) Le caractère donné n'est pas un type d'empaquetage valide, mais l'habitude était de l'ignorer silencieusement.

Invalid type in unpack: '%s'

  • (Type invalide dans unpack : '%s')
  • (F) Le caractère donné n'est pas un type de dépaquetage valide.
  • (W unpack) Le caractère donné n'est pas un type de dépaquetage valide, mais l'habitude était de l'ignorer silencieusement.

ioctl is not implemented

  • (F) Votre machine n'implémente apparemment pas ioctl, ce qui est quelque peu surprenant de la part d'une machine qui supporte le C.

junk on end of regexp

  • (Déchets à la fin de l'expression régulière)
  • (P) L'analyseur d'expressions régulières s'est embrouillé.

Label not found for "last %s"

  • (Étiquette introuvable pour "last %s")
  • (F) Vous avez nommé une boucle pour en sortir, mais vous n'êtes pas actuellement dans une boucle de ce nom, même si vous comptez d'où vous avez été appelé.

Label not found for "next %s"

  • (Étiquette introuvable pour "next %s")
  • (F) Vous avez nommé une boucle pour effectuer l'itération suivante, mais vous n'êtes pas actuellement dans une boucle de ce nom, même si vous comptez d'où vous avez été appelé.

Label not found for "redo %s"

  • (Étiquette introuvable pour "redo %s")
  • (F) Vous avez nommé une boucle pour recommencer l'itération en cours, mais vous n'êtes pas actuellement dans une boucle de ce nom, même si vous comptez d'où vous avez été appelé.

leaving effective %s failed

  • (la sortie de %s effectif a échoué)
  • (F) Alors que le pragma use filetest était actif, l'échange entre les UID ou les GID réels et effectifs a échoué.

listen() on closed socket %s

  • (listen() sur une socket fermée %s)
  • (W closed) Vous avez essayé de faire un listen sur une socket fermée. Peut-être avez-vous oublié de vérifier la valeur renvoyée par votre appel à socket ?

Lvalue subs returning %s not implemented yet

  • (Sous-programmes en tant que lvalue retournant %s pas encore implémentés)
  • (F) À cause de limitations dans l'implémentation actuelle, les valeurs de tableaux et de hachages ne peuvent pas être renvoyées dans un contexte de lvalue.

Malformed PERLLIB_PREFIX

  • (PERLLIB_PREFIX malformée)
  • (F) Il s'agit d'une erreur spécifique à OS/2. PERLLIB_PREFIX doit être de la forme :

     
    Sélectionnez
    prefixe1 ;prefixe2
  • ou :

     
    Sélectionnez
    prefixe1 prefixe2
  • avec prefixe1 et prefixe2 non vides. Si prefixe1 est en fait un préfixe d'un chemin de recherche de bibliothèque interne, on lui substitue prefixe2. L'erreur peut survenir si les composants ne sont pas trouvés ou s'ils sont trop longs. Voir PERLLIB_PREFIX dans le fichier README.os2 inclus dans la distribution de Perl.

Method for operation %s not found in package %s during blessing

  • (La méthode pour l'opération %s n'a pas été trouvée dans le paquetage %s durant la consécration avec bless)
  • (F) Une tentative a été effectuée pour spécifier une entrée dans une table de surcharge qui ne peut être résolue par un sous-programme valide.

Method %s not permitted

  • (Méthode %s interdite)
  • Voir Server error.

Might be a runaway multi-line %s string starting on line %d

  • (%s pourrait être une chaîne galopant sur plusieurs lignes, débutant à la ligne %d)
  • (S) Une suggestion indiquant que l'erreur précédente peut avoir été causée par un séparateur manquant dans une chaîne ou un motif, car la chaîne se finissait éventuellement plus tôt sur la ligne courante.

Misplaced _ in number

  • (_ mal placé dans un nombre)
  • (W syntax) Un caractère souligné dans une constante décimale n'était pas sur une limite de 3 chiffres.

Missing $ on loop variable

  • ($ manquant dans une variable de boucle)
  • (F) Apparemment, vous avez programmé en csh un peu trop longtemps. Les variables en Perl sont toujours précédées du $, au contraire des shells, ou cela peut varier d'une ligne à l'autre.

Missing %sbrace%s on \N{}

  • (%s accolades %s manquantes sur \N{})
  • (F) Vous avez employé la mauvaise syntaxe de nom de caractère littéral \N{nom_caractere} à l'intérieur d'un contexte de guillemets.

Missing comma after first argument to %s function

  • (Virgule manquante après le premier argument de la fonction %s)
  • (F) Alors que certaines fonctions vous permettent de spécifier un handle de fichier ou un « objet indirect » avant la liste d'arguments, celle-ci n'en fait pas partie.

Missing command in piped open

  • (Commande manquante dans un open avec un pipe)
  • (W pipe) Vous avez utilisé la construction open(HF, "| commande") ou, open(HF, "commande |") mais il manquait la commande ou alors elle était vide.

Missing name in "my sub"

  • (Nom manquant dans "my sub")
  • (F) La syntaxe réservée pour les sous-programmes de portée lexicale exige qu'ils aient un nom par lequel on puisse les trouver.

(Missing operator before %s?)

  • (Opérateur manquant avant %s ?)
  • (S) Il s'agit d'une supposition donnée en complément du message « %s found where operator expected ». Souvent l'opérateur manquant est une virgule.

Missing right curly or square bracket

  • (Accolade fermante ou crochet fermant manquant)
  • (F) L'analyseur lexical a compté plus d'accolades ouvrantes ou de crochets ouvrants que d'accolades fermantes ou de crochets fermants. En règle générale, vous trouverez le signe manquant à côté de l'endroit où vous venez d'éditer.

Modification of a read-only value attempted

  • (Tentative de modification d'une valeur en lecture seule)
  • (F) Vous avez essayé, directement ou indirectement, de changer la valeur d'une constante. Vous ne pouvez pas, bien entendu, essayer de faire, 2=1 car le compilateur intercepte ceci. Mais une autre façon simple de faire la même chose est :

     
    Sélectionnez
    sub mod { $_[0] = 1 } mod(2);
  • Un autre moyen serait d'affecter à substr ce qui se trouve au-delà de la fin de la chaîne.

Modification of non-creatable array value attempted, subscript %d

  • (Tentative de modification d'une valeur de impossible à créer, indice %d)
  • (F) Vous avez essayé de faire naître une valeur de tableau et l'indice était probablement négatif, même en comptant à rebours depuis de la fin du tableau.

Modification of non-creatable hash value attempted, subscript "%s"

  • (Tentative de modification d'une valeur de hachage impossible à créer, indice "%s")
  • (P) Vous avez essayé de faire naître une valeur de hachage et elle n'a pu être créée pour une raison particulière.

Module name must be constant

  • (Le nom de module doit être constant)
  • (F) Seul un nom de module brut est permis comme premier argument d'un use.

msg%s not implemented

  • (msg%s non implémenté)
  • (F) Vous n'avez pas d'implémentation de messages des IPC System V sur votre système.

Multidimensional syntax %s not supported

  • (Syntaxe multidimensionnelle %s non supportée)
  • (W syntax) Les tableaux multidimensionnels ne s'écrivent pas $truc[1,2,3]. Ils s'écrivent $truc[1][2][3], tout comme en C.

Name "%s::%s" used only once: possible typo

  • (Nom %s::%s" utilisé une seule fois : faute de frappe possible)
  • (W once) Les fautes de frappe apparaissent fréquemment sous la forme de noms de variable uniques. Si vous avez une bonne raison pour cela, vous n'avez qu'à mentionner la variable à nouveau pour supprimer ce message. La déclaration our est destinée à cela.

Negative length

  • (Longueur négative)
  • (F) Vous avez essayé de faire une opération read/write/send/recv avec un tampon de longueur plus petite que 0. C'est difficile à imaginer.

nested *?+ in regexp

  • (*?+ imbriqué dans l'expression régulière)
  • (F) Vous ne pouvez quantifier un quantifiant sans faire intervenir de parenthèses.
  • Donc les choses comme **, +* ou ?* sont illégales. Remarquez cependant que les quantifiants de recherche de correspondance minimum, *?, +?, et ?? ressemblent à des quantifiants imbriqués, mais ne le sont pas.

No #! line

  • (Pas de ligne #!)
  • (F) L'émulateur setuid exige que le script possède une ligne valide de la forme #! même sur les machines ne supportant pas la construction #!.

No %s allowed while running setuid

  • (Pas de %s autorisé alors que l'on tourne avec setuid)
  • (F) Pour des questions de sécurité, certaines opérations sont trop dangereuses pour être exécutées, voire tentées, dans un script setuid ou setgid. Généralement, il y existera bien un autre moyen pour faire ce que vous voulez, c'est-à-dire que si ce moyen n'est pas sécurisé, il est au moins sécurisable.

No -e allowed in setuid scripts

  • (pas de -e autorisé dans les scripts setuid)
  • (F) Un script setuid ne peut être spécifié par l'utilisateur.

No %s specified for -%c (Pas de %s spécifié pour -%c)

  • (F) L'option de la ligne de commande indiquée nécessite un argument obligatoire, mais vous n'en avez pas spécifié.

No comma allowed after %s

  • (Pas de virgule autorisée après %s)
  • (F) Lorsqu'un opérateur de liste a un handle de fichier ou un « object indirect », il ne doit pas y avoir une virgule ce premier argument et les arguments suivants. Sinon, il serait juste interprété comme tout autre un argument.
  • Une situation ténébreuse dans laquelle ce message se produit est lorsque vous vous attendez à importer une constante dans votre espace de noms avec use ou, import mais qu'une telle importation ne s'est pas produite. Vous auriez dû utiliser une liste d'importation explicite des constantes que vous vous attendiez à voir. Une liste d'importation explicite aurait probablement intercepté cette erreur plus tôt. Ou peut-être s'agit-il seulement d'une erreur de frappe dans le nom de la constante.

No command into which to pipe on command line

  • (Pas de commande dans laquelle envoyer un pipe sur la ligne de commande)
  • (F) Il s'agit d'une erreur spécifique à VMS. Perl effectue ses propres redirections dans la ligne de commande et a trouvé un | à la fin de la ligne de commande, il ne sait donc pas vers où vous voulez rediriger avec un pipe la sortie de cette commande.

No DB::DB routine defined

  • (Pas de routine DB::DB de définie)
  • (F) Le code en train d'être exécuté a été compilé avec l'option -d, mais pour une raison ou pour une autre le fichier perl5db.pl (ou alors un fac-similé) n'a pas défini de routine à appeler au début de chaque instruction. Ce qui est étrange, car le fichier aurait dû être chargé automatiquement et n'a pas pu être analysé correctement.

No dbm on this machine

  • (Pas de dbm sur cette machine)
  • (P) Ceci est compté comme une erreur interne ; chaque machine doit fournir dbm de nos jours, car Perl est livré avec SDBM.

No DBsub routine

  • (Pas de routine DBsub)
  • (F) Le code en train de s'exécuter a été compilé avec l'option -d, mais pour une raison ou pour une autre le fichier perl5db.pl (ou alors un fac-similé) n'a pas défini de routine DB::sub à appeler au début de chaque appel de sous-programme ordinaire.

No error file after 2> or 2>> on command line

  • (Pas de fichier d'erreur après 2> ou 2>> sur la ligne de commande)
  • (F) Il s'agit d'une erreur spécifique à VMS. Perl effectue ses propres redirections dans la ligne de commande et y a trouvé un 2> ou un 2>> mais sans trouver le nom du fichier dans lequel écrire les données destinées à STDERR.

No input file after < on command line

  • (Pas de fichier d'entrée après < sur la ligne de commande)
  • (F) Il s'agit d'une erreur spécifique à VMS. Perl effectue ses propres redirections dans la ligne de commande et y a trouvé un < mais sans trouver le nom du fichier depuis lequel lire les données de STDIN.

No output file after > on command line

  • (Pas de fichier de sortie après 2> ou 2>> sur la ligne de commande)
  • (F) Il s'agit d'une erreur spécifique à VMS. Perl effectue ses propres redirections dans la ligne de commande et a trouvé un > isolé à la fin de la ligne de commande, mais sans savoir où vous vouliez redirigez STDOUT.

No output file after > or >> on command line

  • (Pas de fichier de sortie après > ou >> sur la ligne de commande)
  • (F) Il s'agit d'une erreur spécifique à VMS. Perl effectue ses propres redirection dans la ligne de commande et y a trouvé un > ou un >> mais sans trouver le nom du fichier dans lequel écrire les données destinées à STDOUT.

No package name allowed for variable %s in "our"

  • (Pas de nom de paquetage autorisé pour la variable %s dans "our")
  • (F) Les noms de variable pleinement qualifiés ne sont pas autorisés dans les déclarations, our car cela n'aurait pas beaucoup de sens avec les sémantiques existantes. Une telle syntaxe est réservée pour de futures extensions.

No Perl script found in input

  • (Pas de script Perl trouvé en entrée)
  • (F) Vous avez appelé perl -x, mais aucune ligne n'est trouvée dans le fichier commençant par #! et contenant le mot « perl ».

No setregid available

  • (Pas de setregid de disponible)
  • (F) Configure n'a rien trouvé qui ressemble à l'appel setregid pour votre système.

No setreuid available

  • (Pas de setreuid de disponible)
  • (F) Configure n'a rien trouvé qui ressemble à l'appel setreuid pour votre système.

No space allowed after -%c

  • (Pas d'espace autorisé après -%c)
  • (F) L'argument de l'option de la ligne de commande indiquée doit suivre immédiatement l'option, sans qu'aucun espace n'intervienne.

No such pseudohash field "%s"

  • (Aucun champ de pseudohachage "%s")
  • (F) Vous avez essayé d'accéder à un tableau en tant que hachage, mais le nom de champ utilisé n'est pas défini. Le hachage à l'indice 0 doit faire correspondre tous les noms de champs valides aux indices du tableau pour que cela fonctionne.

No such pseudohash field "%s" in variable %s of type %s

  • (Aucun champ de pseudohachage "%s" dans la variable %s de type %s)
  • (F) Vous avez essayé d'accéder à un champ d'une variable typée, mais le type ignore le nom du champ. Les noms de champ sont recherchés dans le hachage %FIELDS dans le paquetage du type à la compilation. Le hachage %FIELDS est généralement initialisé avec le pragma fields.

No such pipe open

  • (Aucun pipe ouvert)
  • (P) Il s'agit d'une erreur spécifique à VMS. La routine interne my_pclose a essayé de fermer un pipe qui n'avait pas été ouvert. Ceci aurait dû être capturé plus tôt comme une tentative de fermeture d'un handle de fichier non ouvert.

No such signal: SIG%s

  • (Aucun signal : SIG%s)
  • (W signal) Le nom de signal que vous avez spécifié comme indice de %SIG n'a pas été reconnu. Faites kill -l dans votre shell pour voir les noms de signaux valides sur votre système.

No UTC offset information; assuming local time is UTC

  • (Pas d'information sur le décalage UTC ; adopte UTC comme heure locale)
  • (S) Il s'agit d'un avertissement spécifique à VMS. Perl a été incapable de trouver le décalage horaire pour l'heure locale, il a donc supposé que l'heure locale du système et UTC étaient équivalentes. SI ce n'est pas le cas, définissez le nom logique SYS$TIMEZONE_DIFFERENTIAL pour qu'il traduise le nombre de secondes à ajouter à UTC afin d'obtenir l'heure locale.

Not a CODE reference

  • (Non une référence de CODE)
  • (F) Perl a essayé d'évaluer une référence vers une valeur de code (c'est-à-dire un sous-programme), mais a trouvé une référence vers quelque chose d'autre à la place. Vous pouvez utiliser la fonction ref pour trouver de quelle sorte de référence il s'agissait exactement.

Not a format reference

  • (Non une référence de format)
  • (F) Nous ne sommes pas sûrs de la manière dont vous vous arrangez pour générer une référence vers un format anonyme, mais ce message indique que vous l'avez fait et que cela n'existe pas.

Not a GLOB reference

  • (Non une référence de GLOB)
  • (F) Perl a essayé d'évaluer une référence vers un « typeglob » (c'est-à-dire une entrée dans la table des symboles ressemblant à *truc), mais a trouvé une référence vers quelque chose d'autre à la place. Vous pouvez utiliser la fonction ref pour trouver de quelle sorte de référence il s'agissait exactement.

Not a HASH reference

  • (Non une référence de HACHAGE)
  • (F) Perl a essayé d'évaluer une référence vers une valeur de hachage, mais a trouvé une référence vers quelque chose d'autre à la place. Vous pouvez utiliser la fonction ref pour trouver de quelle sorte de référence il s'agissait exactement.

Not a perl script

  • (Non un script perl)
  • (F) L'émulateur setuid exige que le script possède une ligne valide de la forme #! même sur les machines ne supportant pas la construction #!. La ligne doit mentionner « perl ».

Not a SCALAR reference

  • (Non une référence de SCALAIRE)
  • (F) Perl a essayé d'évaluer une référence vers une valeur scalaire, mais a trouvé une référence vers quelque chose d'autre à la place. Vous pouvez utiliser la fonction ref pour trouver de quelle sorte de référence il s'agissait exactement.

Not a subroutine reference

  • (Non une référence de sous-programme)
  • (F) Perl a essayé d'évaluer une référence vers une valeur de code (c'est-à-dire un sous-programme), mais a trouvé une référence vers quelque chose d'autre à la place. Vous pouvez utiliser la fonction ref pour trouver de quelle sorte de référence il s'agissait exactement.

Not a subroutine reference in overload table

  • (Non une référence de sous-programme dans la table de surcharge)
  • (F) Une tentative a été faite pour spécifier une entrée dans une table de surcharge qui ne pointe pas d'une façon ou d'une autre vers un sous-programme valide.

Not an ARRAY reference

  • (Non une référence de TABLEAU)
  • (F) Perl a essayé d'évaluer une référence vers une valeur de tableau, mais a trouvé une référence vers quelque chose d'autre à la place. Vous pouvez utiliser la fonction ref pour trouver de quelle sorte de référence il s'agissait exactement.

Not enough arguments for %s

  • (Pas assez d'arguments pour %s)
  • (F) La fonction exige plus d'arguments que vous n'en avez spécifié.

Not enough format arguments

  • (Pas assez d'arguments de format)
  • (W syntax) Un format spécifiait plus de champs d'images que la ligne suivante ne lui en a fourni.

Null filename used

  • (Nom de fichier vide utilisé)
  • (F) Vous ne pouvez exiger un nom de fichier vide, notamment car sur beaucoup de machines ceci signifie le répertoire courant !

Null picture in formline

  • (Image vide dans formline)
  • (F) Le premier argument de formline doit être une spécification de format d'image valide. On a trouvé que cet argument était vide, ce qui signifie probablement que vous lui avez fourni une valeur non initialisée.

NULL OP IN RUN

  • (OP NUL DANS RUN)
  • (P debugging) Une routine interne a appelé run avec un pointer de code d'opération (opcode) nul.

Null realloc

  • (réallocation nulle)
  • (P) Une tentative a eu lieu pour réallouer le pointeur NULL.

NULL regexp argument

  • (argument NUL dans l'expression régulière)
  • (P) Les routines internes de recherche de motifs ont tout explosé.

NULL regexp parameter

  • (paramètre NUL dans l'expression régulière)
  • (P) Les routines internes de recherche de motifs ont perdu la tête.

Number too long

  • (Nombre trop long)
  • (F) Perl limite la représentation des nombres décimaux dans les programmes à environ 250 caractères. Vous avez dépassé cette longueur. Les futures versions de Perl sont susceptibles d'éliminer cette limitation arbitraire. En attendant, essayez d'utiliser la notation scientifique (ex. 1e6 au lieu de 1_000_000).

Octal number > 037777777777 non portable

  • (Nombre octal >037777777777, non portable)
  • (W portable) Le nombre octal que vous avez spécifié est plus grand que 2**32-1 (4 294 967 295) et n'est donc pas portable d'un système à l'autre.

Octal number in vector unsupported

  • (Nombre octal dans un vecteur non supporté)
  • (F) Les nombres commençant par un 0 ne sont actuellement pas autorisés dans les vecteurs. L'interprétation en octal de tels nombres sera peut-être supportée dans une future version.

Odd number of elements in hash assignment

  • (Nombre impair d'éléments dans une affectation de hachage)
  • (W misc) Vous avez spécifié un nombre impair d'éléments pour initialiser un hachage, ce qui est un impair à la règle, car un hachage va avec des paires clef/valeur.

Offset outside string

  • (Décalage en dehors de la chaîne)
  • (F) Vous avez essayé de faire une opération read/write/send/recv avec un décalage pointant en dehors du tampon. Ceci est difficile à imaginer. La seule exception à cette règle est que faire un sysread après un tampon étendra ce tampon et remplira de zéros la nouvelle zone.

oops: oopsAV

  • (gloups : gloupsAV)
  • (S internal) Il s'agit d'un avertissement interne comme quoi la grammaire est abîmée.

oops: oopsHV

  • (gloups gloupsHV)
  • (S internal) Il s'agit d'un avertissement interne indiquant que la grammaire est abîmée.

Operation "%s": no method found, %s

  • (Opération "%s" : aucune méthode trouvée, %s)
  • (F) Une tentative a été faite pour effectuer une opération de surcharge pour laquelle aucun gestionnaire n'a été défini. Alors que certains gestionnaires peuvent être autogénérés en termes d'autres gestionnaires, il n'existe pas de gestionnaire par défaut pour quelque opération que ce soit, à moins que la clef de surcharge fallback soit spécifiée comme étant vraie.

Operator or semicolon missing before %s

  • (Opérateur ou point-virgule manquant avant %s)
  • (S ambiguous) Vous avez utilisé une variable ou un appel de sous-programme là où l'analyseur syntaxique s'attendait à trouver un opérateur. L'analyseur a considéré que vous pensiez vraiment utiliser un opérateur, mais cela est fortement susceptible de s'avérer incorrect. Par exemple, si vous écrivez accidentellement *truc *truc, cela sera interprété comme si vous aviez écrit *truc * 'truc'.

Out of memory!

  • (Dépassement de mémoire !)
  • (X) La fonction interne de Perl malloc a renvoyé 0, ce qui indique que la mémoire restante (ou la mémoire virtuelle) n'a pas suffi à satisfaire la requête. Perl n'a pas d'autre option que de sortir immédiatement.

Out of memory for yacc stack

  • (Dépassement de mémoire pour la pile de yacc)
  • (F) L'analyseur syntaxique yacc a voulu agrandir sa pile pour qu'il puisse continuer son analyse, mais realloc n'a pas voulu lui donner plus de mémoire, virtuelle ou autre.

Out of memory during request for %s

  • (Dépassement de mémoire pendant une requête pour %s)
  • (X|F) La fonction malloc a renvoyé 0, ce qui indique que la mémoire restante (ou la mémoire virtuelle) n'a pas suffi à satisfaire la requête. La requête a été jugée faible, la possibilité de la capturer est donc dépendante de la façon dont Perl a été compilé. Par défaut, elle ne peut être capturée. Cependant, s'il a été compilé à cet effet, Perl peut utiliser le contenu de $^M comme une zone d'urgence après être sorti par die avec ce message. Dans ce cas l'erreur peut-être capturée une seule fois.

Out of memory during "large" request for %s

  • (Dépassement de mémoire pendant une requête « large » pour %s)
  • (F) La fonction malloc a renvoyé 0, ce qui indique que la mémoire restante (ou la mémoire virtuelle) n'a pas suffit à satisfaire la requête. Cependant, la requête a été jugée assez large (par défaut 64K à la compilation), la possibilité de sortir en capturant cette erreur est donc permise.

Out of memory during ridiculously large request

  • (Dépassement de mémoire pendant une requête ridiculement large)
  • (F) Vous ne pouvez allouer plus de 2**31+« epsilon » octets. Cette erreur est généralement causée par une faute de frappe dans le programme Perl (ex. $tab[time] au lieu de $tab[$time]).

page overflow

  • (dépassement de page mémoire)
  • (W io) Un seul appel à write a produit plus de lignes que ne peut en contenir une page.

panic: ck_grep

  • (panique : ck_grep)
  • (P) Le programme a échoué sur un test de cohérence interne en essayant de compiler un grep.

panic: ck_split

  • (panique : ck_split)
  • (P) Le programme a échoué sur un test de cohérence interne en essayant de compiler un split.

panic: corrupt saved stack index

  • (panique : index de la pile de sauvegarde corrompu)
  • (P) On a demandé à la pile de sauvegarde de restaurer plus de valeurs localisées qu'il n'en existe.

panic: del_backref

  • (panique : référence arrière supprimée)
  • (P) Le programme a échoué sur un test de cohérence interne en essayant de réinitialiser une référence lâche (weak reference).

panic: die %s

  • (panique : die %s)
  • (P) Nous avons passé l'élément du dessus de la pile de contexte à un contexte d'eval pour découvrir alors que l'on n'était pas dans un contexte d'eval.

panic: do_match

  • (panique : do_match)
  • (P) La routine interne pp_match a été appelée avec des données opérationnelles invalides.

panic: do_split

  • (panique : do_split)
  • (P) Quelque chose de terrible s'est mal passé lors de la préparation pour un split.

panic: do_subst

  • (panique : do_subst)
  • (P) La routine interne pp_subst a été appelée avec des données opérationnelles invalides.

panic: do_trans

  • (panique : do_trans)
  • (P) La routine interne do_trans a été appelée avec des données opérationnelles invalides.

panic: frexp

  • (panique : frexp)
  • (P) La fonction de la bibliothèque frexp a échoué, rendant le printf("%f") impossible.

panic: goto

  • (panique : goto)
  • (P) Nous avons passé l'élément du dessus de la pile à un contexte avec l'étiquette spécifiée et découvert ensuite qu'il ne s'agissait pas d'un contexte que nous savions joindre par un goto.

panic: INTERPCASEMOD

  • (panique : INTERPCASEMOD)
  • (P) L'analyseur lexical s'est retrouvé dans un mauvais état à un modificateur de casse (majuscule/minuscule).

panic: INTERPCONCAT

  • (panique : INTERPCONCAT)
  • (P) L'analyseur lexical s'est retrouvé dans un mauvais état en analysant une chaîne de caractères avec des parenthèses.

panic: kid popen errno read

  • (panique : lecture du numéro d'erreur dans le popen d'un fils)
  • (F) Un fils issu d'un fork a renvoyé un message incompréhensible à propose de son numéro d'erreur.

panic: last

  • (panique : last)
  • (P) Nous avons passé l'élément du dessus de la pile à un contexte de bloc et découvert par la suite que ce n'était pas un contexte de bloc.

panic: leave_scope clearsv

  • (panique : clearsv dans la sortie de la portée)
  • (P) Une variable lexicale modifiable est maintenant en lecture seule dans le bloc pour une raison ou pour une autre.

panic: leave_scope inconsistency

  • (panique : sortie de la portée incohérente)
  • (P) La pile de sauvegarde n'est sûrement plus synchronisée. Du moins, il y avait un type enum invalide à son sommet.

panic: malloc

  • (panique : malloc)
  • (P) Quelque chose a demandé un nombre négatif d'octets à malloc.

panic: magic_killbackrefs

  • (panique : suppression magique de toutes les références arrière)
  • (P) Le programme a échoué sur un test de cohérence interne en essayant de réinitialiser toutes les références lâches vers un objet.

panic: mapstart

  • (panique : mapstart)
  • (P) Le compilateur s'est embrouillé avec la fonction map.

panic: null array

  • (panique : tableau nul)
  • (P) On a passé à l'une des routines internes pour les tableaux un pointeur d'AV nul.

panic: pad_alloc

  • (panique : pad_alloc)
  • (P) Le compilateur ne sait plus quelle mémoire de travail (scratchpad) il allouait et libérait les valeurs temporaires et lexicales.

panic: pad_free curpad

  • (panique : pad_free curpad)
  • (P) Le compilateur ne sait plus quelle mémoire de travail (scratchpad) il allouait et libérait les valeurs temporaires et lexicales.

panic: pad_free po

  • (panique : pad_free po)
  • (P) Un décalage incorrect dans la mémoire de travail (scratchpad) a été détecté en interne.

panic: pad_reset curpad

  • (panique : pad_reset curpad)
  • (P) Le compilateur ne sait plus quelle mémoire de travail (scratchpad) il allouait et libérait les valeurs temporaires et lexicales.

panic: pad_sv po

  • (panique : pad_sv po)
  • (P) Un décalage incorrect dans la mémoire de travail (scratchpad) a été détecté en interne.

panic: pad_swipe curpad

  • (panique : pad_swipe curpad)
  • (P) Le compilateur ne sait plus quelle mémoire de travail (scratchpad) il allouait et libérait les valeurs temporaires et lexicales.

panic: pad_swipe po

  • (panique : pad_swipe po)
  • (P) Un décalage incorrect dans la mémoire de travail (scratchpad) a été détecté en interne.

panic: pp_iter

  • (panique : pp_iter)
  • (P) L'itérateur de foreach a été appelé dans un contexte qui n'était pas un contexte de boucle.

panic: realloc

  • (panique : realloc)
  • (P) Quelque chose a demandé un nombre négatif d'octets à realloc.

panic: restartop

  • (panique : restartop)
  • (P) Une routine interne a demandé un goto (ou quelque chose de semblable), mais n'a pas fourni de destination.

panic: return

  • (panique : return)
  • (P) Nous avons passé l'élément du dessus de la pile de contexte à un sous-programme ou à un contexte d'eval pour découvrir alors que l'on n'était ni dans un sous-programme, ni dans un contexte d'eval.

panic: scan_num

  • (panique : scan_num)
  • (P) La fonction interne de Perl scan_num a été appelée sur quelque chose qui n'était pas un nombre.

panic: sv_insert

  • (panique : sv_insert)
  • (P) On a demandé à la routine sv_insert d'enlever plus de chaînes qu'il en existe.

panic: top_env

  • (panique : top_env)
  • (P) Le compilateur a tenté de faire un goto ou quelque chose d'aussi bizarre.

panic: yylex

  • (panique : yylex)
  • (P) L'analyseur lexical s'est retrouvé dans un mauvais état en traitant un modificateur de casse (majuscule/minuscule).

panic: %s

  • (panique : %s)
  • (P) Une erreur interne.

Parentheses missing around "%s" list

  • (Parenthèses manquantes autour de la liste "%s")
  • (W parenthesis) Vous avez écrit quelque chose comme :

     
    Sélectionnez
    my $truc, $machin = @_;
  • alors que vous vouliez dire :

     
    Sélectionnez
    my ($truc, $machin) = @_;
  • Souvenez-vous que my, our et local regroupent plus fortement que la virgule.

Perl %3.3f  required--this is only version %s, stopped

  • (Perl %3.3f requis — il ne s'agit que de la version %s, arrêt)
  • (F) Le module en question utilise des fonctionnalités offertes par une version plus récente que celle exécutée actuellement. Depuis combien de temps n'avez-vous pas fait de remise à niveau ?

PERL_SH_DIR too long

  • (PERL_SH_DIR trop long)
  • (F) Il s'agit d'une erreur spécifique à OS/2. PERL_SH_DIR est le répertoire où se trouve le shell sh. Voir PERL_SH_DIR dans le fichier README.os2 compris dans la distribution de Perl.

Permission denied

  • (Permission refusée)
  • (F) L'émulateur setuid de suidperl a décidé que vous n'étiez pas quelqu'un de bon.

pid %x not a child

  • (le pid %x n'est pas un fils)
  • (W exec) Il s'agit d'une alerte spécifique à VMS ; on a demandé à waitpid d'attendre un processus qui n'est pas un sous-processus du processus courant. Même si cela est correct dans la perspective de VMS, cela n'est probablement pas ce que vous vouliez.

POSIX getpgrp can't take an argument

  • (getpgrp POSIX ne prend pas d'argument)
  • (F) Votre système dispose de la fonction POSIX getpgrp, qui ne prend pas d'argument, au contraire de la version BSD, qui prend un PID.

Possible Y2K bogue: %s

  • (Bogue possible de l'an 2000)
  • (W y2k) Vous êtes en train de concaténer le nombre 19 avec un autre nombre, ce qui pourrait être un problème potentiel pour l'an 2000.

Possible attempt to put comments in qw() list

  • (Tentative possible de mettre des commentaires dans une liste qw())
  • (W qw) Les listes qw contiennent des éléments séparés par des espacements ; comme avec les chaînes littérales, les caractères de commentaires ne sont pas ignorés, mais au lieu de ça traités comme des données littérales. (Vous auriez pu utiliser des délimiteurs différents des parenthèses indiquées ici ; les accolades sont également fréquemment utilisées.) Vous avez probablement écrit quelque chose comme ceci :

     
    Sélectionnez
    @liste = qw(
        a   # un commentaire
        b   # un autre commentaire
    );
  • alors que vous auriez dû écrire cela :

     
    Sélectionnez
    @liste = qw(
        a
        b
    );
  • Si vous voulez vraiment des commentaires, construisez votre liste à l'ancienne, avec des apostrophes et des virgules :
 
Sélectionnez
@liste = (
    'a', # un commentaire
    'b', # un autre commentaire
);

Possible attempt to separate words with commas

  • (Tentative possible de séparer les mots avec des virgules)
  • (W qw) Les listes qw contiennent des éléments séparés par des espacements ; les virgules ne sont donc pas nécessaires pour séparer les éléments. (Vous auriez pu utiliser des délimiteurs différents des parenthèses indiquées ici ; les accolades sont également fréquemment utilisées.)
  • Vous avez probablement écrit quelque chose comme ceci :

     
    Sélectionnez
    qw( a,b, c );
  • ce qui place les caractères virgules parmi certains éléments de la liste. Écrivez-le sans virgules si vous ne voulez pas les voir apparaître dans vos données :
 
Sélectionnez
qw( a b c );

Possible memory corruption: %s overflowed 3rd argument

  • (Corruption possible de la mémoire : le 3e argument de %s a débordé)
  • (F) Un ioctl ou un fcntl a renvoyé plus que ce Perl demandait. Perl anticipe un tampon de taille raisonnable, mais place un octet de sentinelle à la fin du tampon au cas où. On a écrasé cet octet de sentinelle et Perl suppose que la mémoire est maintenant corrompue.

pragma "attrs" is deprecated, use "sub NAME : ATTRS" instead

  • (le pragma "attrs" est déprécié, utilisez à la place "sub NOM : ATTRS")
  • (W deprecated) Vous avez écrit quelque chose comme ceci :

     
    Sélectionnez
    sub fait {
        use attrs qw(locked)
    }
  • Vous auriez dû utiliser à la place la nouvelle syntaxe de déclaration :

     
    Sélectionnez
    sub fait : locked
    {
        ...
  • Le pragma use attrs est maintenant obsolète et n'est fourni que pour assurer une compatibilité antérieure.

Precedence problem: open %s should be open(%s)

  • (Problème de précédence : open %s devrait être open(%s))
  • (S precedence) L'ancienne construction irrégulière :

     
    Sélectionnez
    open TRUC || die;
  • est maintenant mal interprétée en :

     
    Sélectionnez
    open(TRUC || die);
  • à cause la stricte régularisation de la grammaire de Perl 5 en opérateurs unaires et opérateur de listes. (L'ancien open était un peu des deux.) Vous devez mettre des parenthèses autour du handle de fichier ou utiliser le nouvel opérateur or à la place de ||.

Premature end of script headers

  • (Fin prématurée des en-têtes du script)
  • Voir Server error.

print() on closed filehandle %s

  • (print() sur le handle de fichier fermé %s)
  • (W closed) Le handle de fichier dans lequel vous imprimez s'est retrouvé fermé à un moment auparavant. Vérifier le flux logique de votre programme.

printf() on closed filehandle %s

  • (printf() sur le handle de fichier fermé %s)
  • (W closed) Le handle de fichier dans lequel vous écrivez s'est retrouvé fermé à un moment auparavant. Vérifier le flux logique de votre programme.

Process terminated by SIG%s

  • (Processus terminé par SIG%s)
  • (W) Il s'agit d'un message standard formulé par les applications OS/2, alors que les applications Unix meurent en silence. C'est considéré comme une caractéristique du portage sous OS/2. Cet avertissement peut facilement être désactivé en positionnant les gestionnaires de signaux appropriés. Voir également « Process terminated by SIGTERM/SIGINT » (N.d.T. : Processus terminé par SIGTERM/SIGINT) dans le fichier README.os2 livré avec la distribution de Perl.

Prototype mismatch: %s vs %s

  • (Non correspondance de prototypes : %s contre %s)
  • (S) La sous-fonction qui est en train d'être déclarée ou définie a été précédemment déclarée ou définie avec un prototype différent.

Range iterator outside integer range

  • (Itérateur d'intervalle en dehors d'un intervalle)
  • (F) L'un (ou les deux) des arguments numériques de l'opérateur d'intervalle .. est en dehors de l'intervalle qui peut être représenté en interne par des entiers. Contourner cela est en forçant Perl à utiliser des incréments de chaînes magiques en ajoutant 0 au début de vos nombres.

readline() on closed filehandle %s

  • (readline() sur un handle de fichier fermé %s)
  • (W closed) Le handle de fichier dans lequel vous êtes en train de lire s'est retrouvé fermé un moment auparavant. Vérifier le flux logique de votre programme.

realloc() of freed memory ignored

  • (realloc() sur de la mémoire libérée, ignoré)
  • (S malloc) Une routine interne a appelé realloc sur quelque chose qui avait déjà été libéré.

Reallocation too large: %lx

  • (Réallocation trop grande : %lx)
  • (F) Vous ne pouvez allouez plus de 64K sur une machine MS-DOS.

Recompile perl with -DDEBUGGING to use -D switch

  • (Recompilez Perl avec -DDEBUGGING pour utiliser l'option -D)
  • (F debugging) Vous ne pouvez utiliser l'option -D que si Perl a été compilé avec le code qui produit la sortie désirée ; comme cela implique une certaine surcharge, cela n'a pas été inclus dans votre installation de Perl.

Recursive inheritance detected in package '%s'

  • (Héritage récursif détecté dans le paquetage '%s')
  • (F) Plus de 100 niveaux d'héritage ont été utilisés. Ceci indique probablement une boucle accidentelle dans votre hiérarchie de classes.

Recursive inheritance detected while looking for method '%s' in package '%s'

  • (Héritage récursif détecté en recherchant la méthode '%s' dans le paquetage '%s')
  • (F) Plus de 100 niveaux d'héritages ont été utilisés. Ceci indique probablement une boucle accidentelle dans votre hiérarchie de classes.

Reference found where even-sized list expected

  • (Référence trouvée où une liste de taille paire était attendue)
  • (W misc) Vous avez donné une seule référence là où Perl s'attendait à avoir une liste avec un nombre pair d'éléments (pour affection à un hachage). Cela veut habituellement dire que vous avez utilisé le constructeur de hachage anonyme alors que vous vouliez utiliser des parenthèses. Dans tous les cas, un hachage exige des paires clef/valeur.
 
Sélectionnez
%hachage = { un => 1, deux => 2, };         # MAUVAIS
%hachage = [ qw( un tableau anonyme /)];    # MAUVAIS
%hachage = ( un => 1, deux => 2, );         # juste
%hachage = qw( un 1 deux 2 );               # également correct

Reference is already weak

  • (La référence est déjà lâche)
  • (W misc) Vous avez tenté de relâcher une référence qui était déjà lâche. Ceci n'a aucun effet.

Reference miscount in sv_replace()

  • (Mauvais compte de références dans sv_replace())
  • (W internal) On a passé à la fonction interne sv_replace un nouvel SV avec un nombre de références différent de 1.

regexp *+ operand could be empty

  • (L'opérande *+ de l'expression régulière pourrait être vide)
  • (F) La partie d'une expression régulière sujette au quantifiant * ou + pourrait correspondre à une chaîne vide.

regexp memory corruption

  • (Corruption de la mémoire de l'expression régulière)
  • (P) Le moteur d'expressions régulières s'est trompé avec ce que l'expression régulière lui a donné.

regexp out of space

  • (Plus d'espace pour l'expression régulière)
  • (P) Il s'agit d'une erreur « qui ne peut pas arriver », car safemalloc aurait dû la capturer plus tôt.

Reversed %s= operator

  • (Opérateur %s= inversé)
  • (W syntax) Vous avez écrit votre opérateur d'affectation à l'envers. Le = doit toujours arriver en dernier, pour éviter l'ambiguïté avec les opérateurs unaires suivants.

Runaway format

  • (Format s'échappant)
  • (F) Votre format contenait la séquence de répétition jusqu'à un caractère blanc, ~~ mais il a produit 200 lignes d'un coup et la 200e ligne ressemblait exactement à la 199e. Apparemment vous ne vous êtes pas arrangé pour que les arguments soient consommés, soit en utilisant ^ au lieu de @ (pour les variables scalaires), soit en faisant un shift ou un pop (pour les variables de tableaux).

Scalar value @%s[%s] better written as $%s[%s]

  • (Valeur scalaire @%s[%s] mieux écrite avec $%s[%s])
  • (W syntax) Vous avez utilisé une tranche de tableau (indiqué par @) pour sélectionner un seul élément d'un tableau. Généralement il vaut mieux demander une valeur scalaire (indiquée par $). La différence est que $truc[&machin] se comporte toujours comme un scalaire, à la fois lors de son affectation et lors de l'évaluation de son argument, alors que @truc[&machin] se comporte comme une liste lorsque vous y affectez quelque chose en fournissant un contexte de liste à son indice, ce qui peut donner des choses étranges si vous vous attendez à un seul indice. D'un autre côté, si vous espériez vraiment traiter l'élément du tableau comme une liste, vous devez regarder comment fonctionnent les références, car Perl ne va pas par magie faire la conversion entre les scalaires et les listes à votre place.

Scalar value @%s{%s} better written as $%s{%s}

  • (Valeur scalaire @%s{%s} mieux écrite avec $%s{%s})
  • (W syntax) Vous avez utilisé une tranche de hachage (indiquée par @) pour sélectionner un seul élément d'un hachage. Généralement il vaut mieux demander une valeur scalaire (indiquée par $). La différence est que $truc{&machin} se comporte toujours comme un scalaire, à la fois lors de son affectation et lors de l'évaluation de son argument, alors que @truc{&machin} se comporte comme une liste lorsque vous y affectez quelque chose en fournissant un contexte de liste à son indice, ce qui peut donner des choses étranges si vous vous attendez à un seul indice. D'un autre côté, si vous espériez vraiment traiter l'élément du hachage comme une liste, vous devez regarder comment fonctionnent les références, car Perl ne va pas par magie faire la conversion entre les scalaires et les listes à votre place.

Script is not setuid/setgid in suidperl

  • (Le script n'est pas en setuid/setgid dans suidperl)
  • (F) Curieusement, le programme suidperl a été invoqué sur un script qui n'a pas de bit setuid ou setgid bit positionné. Cela n'a vraiment aucun sens.

Search pattern not terminated

  • (Motif de recherche non terminé)
  • (F) L'analyseur lexical n'a pas pu trouver le délimiteur final d'une construction // ou m{}. Souvenez-vous que les délimiteurs fonctionnant par paires « ouvrant/fermant » (tels que les parenthèses, les crochets, les accolades ou les signes inférieur/supérieur) comptent les niveaux imbriqués. Omettre le $ au début d'une variable $m peut causer cette erreur.

%sseek() on unopened file

  • (%sseek() sur un fichier non ouvert)
  • (W unopened) Vous avez essayé d'utiliser la fonction seek ou sysseek sur un handle de fichier qui soit n'a jamais été ouvert, soit a été fermé depuis.

select not implemented

  • (select non implémenté)
  • (F) Cette machine n'implémente pas l'appel système select.

sem%s not implemented

  • (sem%s non implémenté)
  • (F) Vous n'avez pas d'implémentation des sémaphores des IPC System V sur votre système.

semi-panic: attempt to dup freed string

  • (Demi-panique : tentative de dupliquer une chaîne libérée)
  • (S internal) La routine interne newSVsv a été appelée pour dupliquer un scalaire qui avait été marqué auparavant comme étant libre.

Semicolon seems to be missing

  • (Il semble manquer un point-virgule)
  • (W semicolon) Une quasi-erreur de syntaxe a probablement été causée par un point-virgule manquant ou un autre opérateur manquant peut-être, comme une virgule.

send() on closed socket

  • (send() sur une socket fermée)
  • (W closed) La socket dans laquelle vous envoyer des données s'est retrouvée fermée à un moment auparavant. Vérifiez le flux logique de votre programme.

Sequence (? incomplete

  • (Séquence (? incomplète)
  • (F) Une expression régulière finissait par une extension incomplète (?.

Sequence (?#... not terminated

  • (Séquence (?... non terminée)
  • (F) Un commentaire d'une expression régulière doit se terminer par une parenthèse fermée. Les parenthèses imbriquées ne sont pas autorisées.

Sequence (?%s...) not implemented

  • (Séquence (?%s...) non implémentée)
  • (F) Une proposition d'extension des expressions régulières a réservé le caractère, mais n'a pas encore été écrite.

Sequence (?%s...) not recognized

  • (Séquence (?%s...) non reconnue)
  • (F) Vous avez utilisé une expression régulière qui n'a aucun sens.

Server error

  • (Erreur du serveur)
  • Il s'agit du message d'erreur généralement vu dans une fenêtre de navigateur lorsque vous essayez de lancer un programme CGI (y compris SSI) sur le Web. Le véritable texte d'erreur varie largement d'un serveur à l'autre. Les variantes les plus fréquemment vues sont « 500 Server error », « Method (something) not permitted », « Document contains no data », « Premature end of script headers » et « Did not produce a valid header » (« Erreur de serveur 500 », « Méthode (quelque_chose) non permise », « Le document ne contient aucune donnée », « Fin prématurée des en-têtes de script » et « N'a pas produit d'en-tête valide »).
  • Il s'agit d'une erreur CGI, non d'une erreur Perl.
  • Vous devez vous assurer que votre script soit exécutable, accessible par l'utilisateur sous lequel le script CGI tourne (qui n'est probablement pas le compte utilisateur sous lequel vous avez fait vos tests), qu'il ne repose sur aucune variable d'environnement (telle que PATH) que l'utilisateur ne va pas avoir et qu'il ne se trouve pas à un emplacement inatteignables pour le serveur CGI. Pour plus d'informations, merci de voir les liens suivants :

  • Vous devriez également regarder la FAQ Perl.

setegid() not implemented

  • (setegid() non implémenté)
  • (F) Vous avez essayé d'affecter, $) mais votre système d'exploitation ne supporte pas l'appel système setegid (ou un équivalent) ou du moins c'est ce que pense Configure.

seteuid() not implemented

  • (seteuid() non implémenté)
  • (F) Vous avez essayé d'affecter, $> mais votre système d'exploitation ne supporte pas l'appel système seteuid (ou un équivalent) ou du moins c'est ce que pense Configure.

setpgrp can't take arguments

  • (setpgrp ne peut pas prendre d'arguments)
  • (F) Votre système dispose de la fonction setpgrp de BSD 4.2, qui ne prend pas d'argument, au contraire de setpgid POSIX, qui prend un ID de processus et un ID de groupe de processus.

setrgid() not implemented

  • (setrgid() non implémenté)
  • (F) Vous avez essayé d'affecter, $( mais votre système d'exploitation ne supporte pas l'appel système setrgid (ou un équivalent) ou du moins c'est ce que pense Configure.

setruid() not implemented

  • (setruid() non implémenté)
  • (F) Vous avez essayé d'affecter, $< mais votre système d'exploitation ne supporte pas l'appel système setruid (ou un équivalent) ou du moins c'est ce que pense Configure.

setsockopt() on closed socket %s

  • (setsockopt() sur une socket fermée %s)
  • (W closed) Vous avez essayé de positionner des options sur une socket fermée. Peut-être avez-vous oublié de vérifier la valeur renvoyée par votre appel à socket ?

Setuid/gid script is writable by world

  • (Script setuid/setgid modifiable par le monde entier)
  • (F) L'émulateur setuid ne lancera pas un script modifiable par le monde entier, car le monde entier peut très bien déjà l'avoir modifié.

shm%s not implemented

  • (shm%s non implémenté)
  • (F) Vous n'avez pas d'implémentation de la mémoire partagée des IPC System V sur votre système.

shutdown() on closed socket %s

  • (shutdown() sur une socket fermée %s)
  • (W closed) Vous avez essayé de faire un shutdown sur socket fermée. Cela semble quelque peu superflu.

SIG%s handler "%s" not defined

  • (Gestionnaire "%s" pour SIG%s non défini)
  • (W signal) Le gestionnaire pour le signal nommé dans %SIG n'existe en fait pas. Peut-être l'avez-vous mis dans le mauvais paquetage ?

sort is now a reserved word

  • (sort est maintenant un mot réservé)
  • (F) Il s'agit d'un ancien message d'erreur que pratiquement personne ne rencontrera plus. Mais avant que sort soit un mot-clef, les gens l'utilisaient parfois comme un handle de fichier.

Sort subroutine didn't return a numeric value

  • (Le sous-programme de sort n'a pas renvoyé de valeur numérique)
  • (F) Une routine de comparaison pour sort doit retourner un nombre. Vous l'avez probablement foutu en l'air en n'utilisant pas <=> ou cmp, ou en ne les utilisant pas correctement.

Sort subroutine didn't return single value

  • (Le sous-programme de sort n'a pas renvoyé une valeur unique)
  • (F) Une routine de comparaison pour sort ne peut pas renvoyer une valeur de liste avec plus ou moins d'un élément.

Split loop

  • (Boucle dans un split)
  • (P) Le split bouclait sans fin. (Évidemment, un split ne devrait boucler plus de fois qu'il n'y a de caractères en entrée, ce qui s'est passé.)

Stat on unopened file <%s>

  • (stat sur un fichier non ouvert <%s>)
  • (W unopened) Vous avez essayé d'utiliser la fonction stat (ou un test de fichier équivalent) sur un handle de fichier qui n'a jamais été ouvert ou qui a été fermé depuis.

Statement unlikely to be reached

  • (Instruction peu susceptible d'être atteinte)
  • (W exec) Vous avez fait un exec avec des instructions le suivant autres qu'un die. Il s'agit presque toujours d'une erreur, car exec ne revient jamais à moins qu'il n'y ait une erreur. Vous vouliez probablement utiliser system à la place, qui lui revient. Pour supprimer cet avertissement, mettez-le exec dans un bloc tout seul.

Strange *+?{} on zero-length expression

  • (*+?{} étrange sur une expression de longueur nulle)
  • (W regexp) Vous avez appliqué un quantifiant d'expression régulière à un endroit où cela n'a aucun sens, comme dans une assertion de longueur nulle. Essayez de plutôt mettre le quantifiant à l'intérieur de l'assertion. Par exemple, le moyen de réussir la correspondance avec abc, si c'est suivi par trois répétitions de xyz est /abc(?=(?:xyz){3})/, et non /abc(?=xyz){3}/.

Stub found while resolving method '%s' overloading '%s' in package '%s'

  • (Souche trouvée lors de la résolution de la méthode '%s' surchargeant '%s' dans le paquetage '%s')
  • (P) La résolution de la surcharge dans l'arbre @ISA a peut être été rompue par des souches (stubs) d'importation. Les souches ne devraient jamais être implicitement créées, mais les appels explicites à can peuvent rompre cela.

Subroutine %s redefined

  • (Sous-programme %s redéfini)
  • (W redefine) Vous avez redéfini un sous-programme. Pour supprimer cet avertissement, écrivez :
 
Sélectionnez
{
    no warnings;
    eval "sub name { ... }";
}

Substitution loop

  • (Boucle dans une substitution)
  • (P) La substitution boucle sans fin. (Évidemment, une substitution ne devrait boucler plus de fois qu'il n'y a de caractères en entrée, ce qui s'est passé.)

Substitution pattern not terminated

  • (Motif pour la substitution non terminé)
  • (F) L'analyseur lexical ne peut trouver le délimiteur intérieur d'une construction s/// ou s{}{}. Souvenez-vous que les délimiteurs fonctionnant par paires « ouvrant/fermant » (tels que les parenthèses, les crochets, les accolades ou les signes inférieur/supérieur) comptent les niveaux imbriqués. Omettre le $ au début d'une variable $s peut causer cette erreur.

Substitution replacement not terminated

  • (Remplacement pour la substitution non terminé)
  • (F) L'analyseur lexical ne peut trouver le délimiteur final d'une construction s/// ou s{}{}. Souvenez-vous que les délimiteurs fonctionnant par paires « ouvrant/fermant » (tels que les parenthèses, les crochets, les accolades ou les signes inférieur/supérieur) comptent les niveaux imbriqués. Omettre le $ au début d'une variable $s peut causer cette erreur.

substr outside of string

  • (substr à l'extérieur d'une chaîne)
  • (W substr|F) Vous avez essayé de référencer un substr qui pointait en dehors d'une chaîne. C'est-à-dire que la valeur absolue du décalage est plus grande que la longueur de la chaîne. Cet avertissement est fatal si substr est utilisé dans un contexte de lvalue (par exemple comme opérateur du côté gauche d'une affectation ou comme argument d'un sous-programme).

suidperl is no longer needed since %s

  • (suidperl n'est plus nécessaire depuis %s)
  • (F) Votre Perl a été compilé avec -DSETUID_SCRIPTS_ARE_SECURE_NOW, mais une version de l'émulateur setuid est tout de même arrivé à se lancer d'une manière ou d'une autre.

switching effective %s is not implemented

  • (l'échange de %s effectif n'est pas implémenté)
  • (F) Avec le pragma use filetest actif, nous ne pouvons pas échanger les UID ou les GID réels et effectifs.

syntax error

  • (erreur de syntaxe)
  • (F) Ce message veut probablement dire que vous avez eu une erreur de syntaxe. Les raisons habituelles incluent :

    • un mot-clef est mal orthographié ;
    • il manque un point-virgule ;
    • il manque une virgule ;
    • il manque une parenthèse ouvrante ou fermante ;
    • il manque un crochet ouvrant ou fermant ;
    • il manque une apostrophe ou un guillemet fermant.
  • Souvent un autre message sera associé avec l'erreur de syntaxe donnant plus d'informations. (Parfois, cela aide d'activer -w.) Le message d'erreur en lui-même dit souvent à quel endroit de la ligne Perl a décidé de s'arrêter. Parfois la véritable erreur se trouve quelques tokens avant, car Perl est doué pour comprendre ce que l'on entre aléatoirement. Occasionnellement, le numéro de ligne peut être inexact et la seule manière de savoir ce qui ce passe est d'appeler de façon répétitive, une fois tous les 36 du mois, perl -c en éliminant à chaque fois la moitié du programme pour voir où l'erreur disparaît. Il s'agit d'une sorte de version cybernétique du jeu des 20 questions.

syntax error at line %d:'%s' unexpected

  • (erreur de syntaxe à la ligne %d :'%s' inattendu)
  • (A) Vous avez accidentellement lancé votre script via le Bourne shell au lieu de Perl. Vérifiez la ligne #! ou lancez vous-même votre script manuellement dans Perl avec perl nom_script.

System V %s is not implemented on this machine

  • (%s de System V n'est pas implémenté sur cette machine)
  • (F) Vous avez essayé de faire quelque chose avec une fonction commençant par sem, shm ou, msg mais cet IPC System V n'est pas implémenté sur votre machine. (Sur certaines machines, la fonctionnalité peut exister, mais peut ne pas être configurée.)

syswrite() on closed filehandle

  • (syswrite() sur un handle de fichier fermé)
  • (W closed) Le handle de fichier dans lequel vous écrivez s'est retrouvé fermé à un moment auparavant. Vérifiez le flux logique de votre programme.

Target of goto is too deeply nested

  • (La cible du goto est trop profondément imbriquée)
  • (F) Vous avez essayé d'utiliser goto pour atteindre une étiquette qui était trop profondément imbriquée pour que Perl puisse l'atteindre. Perl vous fait une faveur en vous le refusant.

tell() on unopened file

  • (tell() sur un fichier non ouvert)
  • (W unopened) Vous avez essayé d'utiliser la fonction tell() sur un handle de fichier qui n'a jamais été ouvert ou qui a été fermé depuis.

Test on unopened file %s

  • (Test sur un fichier non ouvert %s)
  • (W unopened) Vous avez essayé d'invoquer un opérateur de test de fichier sur un handle de fichier qui n'est pas ouvert. Vérifiez votre logique.

That use of $[ is unsupported

  • (Cette utilisation de $[ n'est pas supportée)
  • (F) L'affectation de $[ est maintenant strictement circonscrite et interprétée comme une directive de compilation. Vous devez maintenant écrire une seule possibilité parmi celles-ci :

     
    Sélectionnez
    $[ = 0;
    $[ = 1;
    ...
    local $[ = 0;
    local $[ = 1;
    ...
  • Ceci est imposé pour prévenir le problème d'un module changeant la base des tableaux depuis un autre module par inadvertance.

The %s function is unimplemented

  • (La fonction %s n'est pas implémentée)
  • La fonction indiquée n'est pas implémentée sur cette architecture, selon les tests de Configure.

The crypt() function is unimplemented due to excessive paranoia

  • (La fonction crypt() n'est pas implémentée à cause d'une paranoïa excessive)
  • (F) Configure n'a pas pu trouver la fonction crypt sur votre machine, probablement parce que votre vendeur ne l'a pas fournie, probablement parce qu'il pense que le gouvernement des États-Unis pense que c'est un secret ou du moins continue à prétendre que c'en est un.

The stat preceding -l _ wasn't an lstat

  • (Le stat précédant -l _ n'était pas un lstat)
  • (F) Cela n'a pas de sens de vérifier si le tampon courant de stat est un lien symbolique si le dernier stat que vous avez écrit dans le tampon a déjà passé le lien symbolique pour obtenir le fichier réel. Utilisez un véritable nom de fichier à la place.

This Perl can't reset CRTL environ elements (%s)

  • (Cette copie de Perl ne peut pas réinitialiser les éléments de l'environnement de CRTL (%s))

This Perl can't set CRTL environ elements (%s = %s)

  • (Cette copie de Perl ne peut pas positionner les éléments de l'environnement de CRTL (%s = %s))
  • (W internal) Il s'agit d'avertissements spécifiques à VMS. Vous avez essayé de modifier ou de supprimer un élément du tableau d'environnement interne de CRTL, mais votre copie de Perl n'a pas été compilée avec un CRTL contenant la fonction interne setenv. Vous devrez recompiler Perl avec un CRTL qui le contienne ou redéfinir PERL_ENV_TABLES (voir perlvms(1)) pour que le tableau d'environnement ne soit pas la cible de la modification de %ENV qui a produit cet avertissement.

times not implemented

  • (times non implémenté)
  • (F) Votre version de la bibliothèque C ne fait apparemment pas de times. Je suspecte que vous n'êtes pas sous Unix.

Too few args to syscall

  • (Trop peu d'arguments pour syscall)
  • (F) Il doit y avoir au moins un argument à syscall pour spécifier l'appel système à appeler, pauvre étourdi !

Too late for "-T" option

  • (Trop tard pour l'option "-T")
  • (X) La ligne #! (ou son équivalent local) dans un script Perl contient l'option -T, mais Perl n'a pas été invoqué avec -T sur la ligne de commande. Il s'agit d'une erreur, car le temps que Perl découvre un -T dans un script, il est trop tard pour marquer proprement l'intégralité de l'environnement. Donc Perl abandonne.
  • Si le script Perl a été exécuté en tant que commande en utilisant le mécanisme #! (ou son équivalent local), cette erreur peut habituellement être corrigée en éditant la ligne #! pour que l'option -T fasse partie du premier argument de Perl : ex. changer perl -n -T en perl -T -n.
  • Si le script Perl a été exécuté en tant que perl nom_script alors l'option -T doit apparaître sur la ligne de commande : perl -T nom_script.

Too late for "-%s" option

  • (Trop tard pour l'option « -%s »)
  • (X) La ligne #! (ou son équivalent local) dans un script Perl contient l'option -M ou -m. Il s'agit d' une erreur, car les options -M et -m ne sont pas prévues pour être utilisées à l'intérieur des scripts. Utilisez use à la place.

Too late to run %s bloc

  • (Trop tard pour lancer le bloc %s)
  • (W void) Un bloc CHECK ou INIT a été défini à l'exécution, lorsque l'opportunité de le lancer est déjà passée. Vous chargez peut-être un fichier avec require ou do alors que vous devriez utiliser use à la place. Ou vous devriez peut-être mettre le require ou le do à l'intérieur d'un bloc BEGIN.

Too many ('s

  • (Trop de « ( »)

Too many )'s

  • (trop de « ) »)
  • (A) Vous avez lancé accidentellement votre script via csh au lieu de Perl. Vérifiez la ligne #! ou lancez vous-même votre script manuellement dans Perl avec perl nom_script.

Too many args to syscall

  • (Trop d'argument pour syscall)
  • (F) Perl supporte un maximum de 14 arguments seulement pour syscall.

Too many arguments for %s

  • (Trop d'argument pour %s)
  • (F) La fonction demande moins d'arguments que vous en avez spécifié.

trailing \ in regexp

  • (\ à la fin de l'expression régulière)
  • (F) L'expression régulière se termine par un antislash qui n'est pas protégé par un antislash. Faites-le.

Transliteration pattern not terminated

  • (Motif pour la traduction non terminé)
  • (F) L'analyseur lexical n'a pas pu trouver le délimiteur intérieur d'une construction tr///, tr[][], y/// ou y[][]. Omettre le $ au début des variables $tr ou $y peut causer cette erreur.

Transliteration replacement not terminated

  • (Remplacement pour la traduction non terminé)
  • (F) L'analyseur lexical n'a pas pu trouver le délimiteur final d'une construction tr/// ou tr[][].

truncate not implemented

  • (truncate non implémenté)
  • (F) Votre machine n'implémente pas de mécanisme de troncation de fichier que Configure puisse reconnaître.

Type of arg %d to %s must be %s (not %s)

  • (Le type de l'argument %d de %s doit être %s (pas %s))
  • (F) Cette fonction exige que l'argument à cette position soit d'un certain type. Les tableaux doivent être @NOM ou @{EXPR}. Les hachages doivent être %NOM ou %{EXPR}. Aucun déréférencement implicite n'est permis — utilisez la forme {EXPR} en tant que déréférencement explicite.

umask: argument is missing initial 0

  • (umask : il manque 0 au début de l'argument)
  • (W umask) Un umask de 222 est incorrect. Il devrait être, 0222 car les littéraux octaux commencent toujours par 0 en Perl, tout comme en C.

umask not implemented

  • (umask non implémenté)
  • (F) Votre machine n'implémente pas la fonction umask et vous avez essayé de l'utiliser pour restreindre les permissions pour vous-même. (EXPR & 0700).

Unable to create sub named "%s"

  • (Incapable de créer le sous-programme nommé "%s")
  • (F) Vous avez tenté de créer ou d'accéder à un sous-programme avec un nom illégal.

Unbalanced context: %d more PUSHes than POPs

  • (Contexte déséquilibré : %d PUSH de plus que de POP)
  • (W internal) Le code de sortie a détecté une incohérence interne entre le nombre de contextes d'exécution dans lesquels on est entré et depuis lesquels on est sorti.

Unbalanced saves: %d more saves than restores

  • (Sauvegardes déséquilibrées : %d sauvegardes de plus que de restaurations)
  • (W internal) Le code de sortie a détecté une incohérence interne entre le nombre de variables qui ont été sauvegardées par local.

Unbalanced scopes: %d more ENTERs than LEAVEs

  • (Portées déséquilibrées : %d ENTER de plus que de LEAVE)
  • (W internal) Le code de sortie a détecté une incohérence interne entre le nombre de blocs dans lequel on est rentré et depuis lesquels on est sorti.

Unbalanced tmps: %d more allocs than frees

  • (Valeurs temporaires déséquilibrées : %d allouées de plus que de libérées)
  • (W internal) Le code de sortie a détecté une incohérence interne entre le nombre de scalaires mortels qui ont été alloués et libérés.

Undefined format "%s" called

  • (Format indéfini "%s" appelé)
  • (F) Le format indiqué ne semble pas exister. Peut-être est-il réellement dans un autre paquetage ?

Undefined sort subroutine "%s" called

  • (Sous-programme de sort indéfini "%s" appelé)
  • (F) La routine de comparaison de sort spécifiée ne semble pas exister. Peut-être est-elle dans un autre paquetage?

Undefined subroutine &%s called

  • (Sous-programme indéfini &%s appelé)
  • (F) Le sous-programme indiqué n'a pas été défini ou s'il l'a été, il a été indéfini depuis.

Undefined subroutine called

  • (Sous-programme indéfini appelé)
  • (F) Le sous-programme anonyme que vous essayez d'appeler n'a pas été défini ou s'il l'a été, il a été indéfini depuis.

Undefined subroutine in sort

  • (Sous-programme indéfini dans sort)
  • (F) La routine de comparaison de sort spécifiée est déclarée, mais ne semble pas avoir été définie pour le moment.

Undefined top format "%s" called

  • (Format d'en-tête indéfini "%s" appelé)
  • (F) Le format indiqué ne semble pas exister. Peut-être est-il en réalité dans un autre paquetage?

Undefined value assigned to typeglob

  • (Valeur indéfinie affectée à un typeglob)
  • (W misc) Une valeur indéfinie a été affectée à un typeglob, comme *truc = undef.
  • Ceci n'a aucun effet. Il est possible que vous vouliez dire en réalité undef *truc.

unexec of %s into %s failed!

  • (Échec de l'unexec de %s dans %s !)
  • (F) La routine unexec a échoué pour une raison ou pour une autre. Voir votre représentant local FSF (Free Software Fondation), qui l'a probablement mis là en premier lieu.

Unknown BYTEORDER

  • (BYTEORDER inconnu)
  • (F) Il n'y a aucune fonction d'échange d'octets pour une machine fonctionnant avec cet ordre d'octets.

Unknown open() mode '%s'

  • (Mode d'open() '%s' inconnu)
  • (F) Le deuxième argument d'un open à trois arguments n'est pas dans la liste des modes valides : <, >, >>, +<, +>, +> >, -|, |-.

Unknown process %x sent message to prime_env_iter: %s

  • (Le processus inconnu %x a envoyé un message au prime_env_iter : %s)
  • (P) Il s'agit d'une erreur spécifique à VMS. Perl lisait des valeurs pour %ENV avant de le parcourir et quelqu'un d'autre a collé un message dans le flux de données que Perl attendait. Quelqu'un de très perturbé ou peut-être essayant de subvertir le contenu de %ENV pour Perl dans un but néfaste.

unmatched () in regexp

  • (() sans correspondance dans l'expression régulière)
  • (F) Les parenthèses non protégées par un antislash doivent toujours être équilibrées dans les expressions régulières. Si vous êtes utilisateur de vi, la touche % est parfaitement adaptée pour trouver la parenthèse correspondante.

Unmatched right %s bracket

  • (Signe %s fermant sans correspondance)
  • (F) L'analyseur lexical a compté plus d'accolades ou de crochets fermants que d'ouvrants, vous avez donc probablement oublié de mettre un signe ouvrant correspondant. En règle générale, vous trouverez le signe manquant (si l'on peut s'exprimer ainsi) près de l'endroit où vous étiez en train d'éditer en dernier.

unmatched [] in regexp

  • ([] sans correspondance dans l'expression régulière)
  • (F) Les crochets autour d'une classe de caractères doivent se correspondre. Si vous voulez inclure un crochet fermant dans une classe de caractères, protégez-le avec un antislash ou mettez-le en premier.

Unquoted string "%s" may clash with future reserved word

  • (Chaîne sans guillemets ni apostrophes "%s" susceptible d'être en conflit avec un mot réservé dans le futur)
  • (W reserved) Vous utilisez un mot simple qui pourrait être un jour proclamé comme étant un mot réservé. Le mieux est de mettre un tel mot entre guillemets ou entre apostrophes ou en lettres capitales ou d'insérer un souligné dans son nom. Vous pouvez également le déclarer en tant que sous-programme.

Unrecognized character %s

  • (Caractère %s non reconnu)
  • (F) L'analyseur syntaxique de Perl ne sait absolument pas quoi faire avec le caractère spécifié dans votre script Perl (ou dans un eval). Peut-être avez-vous essayé de lancer un script compressé, un programme binaire ou un répertoire en tant que programme Perl.

Unrecognized escape \\%c passed through

  • (Rencontre d'une séquence d'échappement \\%c non reconnu)
  • (W misc) Vous avez employé une combinaison avec un caractère antislash qui n'est pas reconnu.

Unrecognized signal name "%s"

  • (Nom de signal "%s" non reconnu)
  • (F) Vous avez spécifié un nom de signal à la fonction kill qui n'est pas reconnue. Faites kill -l dans votre shell pour voir les noms de signaux valides sur votre système.

Unrecognized switch: -%s (-h will show valid options)

  • (Option on reconnue : -%s (-h donne les options valides))
  • (F) Vous avez spécifié une option illégale pour Perl. Ne faites pas cela. (Si vous pensez ne pas l'avoir fait, vérifiez la ligne #! pour voir si elle ne spécifie pas la mauvaise option dans votre dos.)

Unsuccessful %s on filename containing newline

  • (Échec de %s sur un nom de fichier contenant un saut de ligne)
  • (W newline) Une opération de fichier a été tentée sur un nom de fichier et cette opération a échoué, probablement parce que le nom de fichier contenait un caractère de saut de ligne, probablement parce que vous avez oublié de le faire sauter par un chop ou un chomp.

Unsupported directory function "%s" called

  • (Fonction "%s" sur les répertoires non supportée appelée)
  • (F) Votre machine ne supporte pas opendir et readdir.

Unsupported function fork

  • (Fonction fork non supportée)
  • (F) Votre version d'exécutable ne supporte pas le fork. Remarquez que sur certains systèmes, comme OS/2, il peut y avoir différentes versions d'exécutables Perl, certaines d'entre elles supportent fork, d'autres non.
  • Essayez de changer le nom que vous utilisez pour appelez Perl en perl_, perl__ et ainsi de suite.

Unsupported function %s

  • (Fonction %s non supportée)
  • (F) Cette machine n'implémente apparemment pas la fonction indiquée ou du moins c'est ce que pense Configure.

Unsupported socket function "%s" called

  • (Fonction "%s" sur les sockets non supportée appelée)
  • (F) Votre machine ne supporte pas le mécanisme des sockets Berkeley ou du moins c'est ce que pense Configure.

Unterminated <> operator

  • (Opérateur <> non terminé)
  • (F) L'analyseur lexical a vu un signe inférieur à un endroit où il s'attendait à un terme, il recherche donc le signe supérieur correspondant et ne le trouve pas. Il y a des chances que vous ayez oublié des parenthèses obligatoires plus tôt dans la même ligne et vous que pensiez vraiment à un < signifiant « inférieur à ».

Unterminated attribute parameter in attribute list

  • (Paramètre d'attribut non terminé dans une liste d'attributs)
  • (F) L'analyseur lexical a vu une parenthèse ouvrante lorsqu'il analysait une liste d'attributs, mais n'a pas trouvé la parenthèse fermante correspondante. Vous devez ajouter (ou enlever) un caractère antislash pour équilibrer vos parenthèses.

Unterminated attribute list

  • (Liste d'attributs non terminée)
  • (F) L'analyseur lexical a trouvé quelque chose d'autre qu'un identificateur simple au début d'un attribut et ce n'était pas un point-virgule ni le début d'un bloc. Peut-être avez-vous terminé trop tôt la liste de paramètres de l'attribut précédent.

Use of $# is deprecated

  • (L'utilisation de $# est dépréciée)
  • (D deprecated) Il s'agissait d'une tentative mal avisée d'émuler une fonctionnalité de awk mal définie. Utilisez plutôt un printf ou sprintf explicite.

Use of $* is deprecated

  • (L'utilisation de $* est dépréciée)
  • (D deprecated) Cette variable activait comme par magie la recherche de motifs en multilignes, à la fois pour vous et pour les sous-programmes malchanceux que vous seriez amené à appeler. Maintenant, vous devriez utiliser les modificateurs //m et //s pour faire cela sans les effets dangereux d'action à distance de $*.

Use of %s in printf format not supported

  • (Utilisation de %s non supportée dans un format de printf)
  • (F) Vous avez essayé d'utiliser une fonctionnalité de printf qui est accessible en C. Cela veut habituellement dire qu'il existe une meilleure manière de faire cela en Perl.

Use of bare << to mean <<"" is deprecated

  • (L'utilisation d'un << brut signifiant <<"" est dépréciée)
  • (D deprecated) Vous êtes maintenant encouragé à utiliser la forme explicite avec des guillemets ou des apostrophes si vous désirez utiliser une ligne vide comme délimiteur final d'un document « ici-même » (here document).

Use of implicit split to @_ is deprecated

  • (L'utilisation d'un split implicite sur @_ est dépréciée)
  • (D deprecated) Vous donnez beaucoup de travail au compilateur lorsque vous écrasez la liste d'arguments d'un sous-programme, il vaut donc mieux affecter explicitement les résultats d'un split à un tableau (ou à une liste).

Use of inherited AUTOLOAD for non-method %s() is deprecated

  • (L'utilisation de l'héritage par AUTOLOAD pour la non-méthode %s() est dépréciée)
  • (D deprecated) Comme fonctionnalité (hum) accidentelle, les sous-programmes AUTOLOAD étaient recherchés de la même façon que les méthodes (en utilisant la hiérarchie de @ISA) même lorsque les sous-programmes à autocharger étaient appelés en tant que fonctions brutes (ex. : Truc::bidule()) et pas en tant que méthodes (par exemple, Truc->bidule() ou $obj->bidule()).
  • Ce bogue a été rectifié dans Perl 5.005, qui utilisait la recherche de méthodes seulement pour l'AUTOLOAD de méthodes. Cependant, il y a une base significative de code existant susceptible d'utiliser l'ancien comportement. Ainsi, en tant qu'étape intermédiaire, Perl 5.004 émettait cet avertissement optionnel quand des non-méthodes utilisaient des AUTOLOAD héritées.
  • La règle simple est la suivante : l'héritage ne fonctionnera pas quand il y a autochargement de non-méthodes. La simple correction pour de l'ancien code est : dans tout module qui avait l'habitude de dépendre de l'héritage d'AUTOLOAD pour les non-méthodes d'une classe de base nommée Classe_Base, exécutez *AUTOLOAD = &Classe_Base::AUTOLOAD au démarrage.
  • Dans le code qui actuellement fait use AutoLoader; @ISA = qw(AutoLoader);, vous pouvez supprimer AutoLoader de @ISA et changer use AutoLoader; en use AutoLoader 'AUTOLOAD';.

Use of reserved word "%s" is deprecated

  • (L'utilisation du mot réservé "%s" est dépréciée)
  • (D deprecated) Le mot simple indiqué est un mot réservé. Les futures versions de Perl peuvent l'utiliser en tant que mot-clef, vous feriez donc mieux de mettre explicitement le mot entre guillemets ou entre apostrophes d'une manière appropriée à son contexte d'utilisation ou d'utiliser de surcroît un nom différent. L'avertissement peut être supprimé pour les noms de sous-programmes en ajoutant un préfixe & ou en qualifiant la variable avec le paquetage, comme &local(), ou Truc::local().

Use of %s is deprecated

  • (L'utilisation de %s est dépréciée)
  • (D deprecated) La construction indiquée n'est plus recommandée, généralement parce qu'il y a une meilleure façon de faire et également parce que l'ancienne méthode a de mauvais effets de bord.

Use of uninitialized value %s

  • (Utilisation d'une valeur non initialisée %s)
  • (W uninitialized) Une valeur indéfinie a été utilisée comme si elle avait déjà été définie. Elle a été interprétée comme un "" ou un, 0 mais peut-être est-ce une erreur. Pour supprimer cet avertissement, affectez une valeur définie à vos variables.

Useless use of "re" pragma

  • (Utilisation inutile du pragma "re")
  • (W) Vous avez fait un use re sans aucun argument. Ceci n'est vraiment pas très utile.

Useless use of %s in void context

  • (Utilisation inutile de %s dans un contexte vide)
  • (W void) Vous avez fait quelque chose sans effet de bord dans un contexte qui ne fait rien de la valeur de retour, comme une instruction ne renvoyant pas de valeur depuis un bloc ou le côté gauche d'un opérateur scalaire virgule. Par exemple, vous obtiendrez ceci si vous confondez les précédences en C avec les précédences en Python en écrivant :

     
    Sélectionnez
    $un, $deux = 1, 2;
  • alors que vous vouliez dire :

     
    Sélectionnez
    ($un, $deux) = (1, 2);
  • Une autre erreur courante est l'utilisation de parenthèses ordinaires pour construire une liste de références alors vous devriez utiliser des accolades ou des crochets, par exemple, si vous écrivez :

     
    Sélectionnez
    $tableau = (1,2);
  • alors que vous vouliez dire :

     
    Sélectionnez
    $tableau = [1,2];
  • Les crochets transforment explicitement une valeur de liste en une valeur scalaire tandis que les parenthèses ne le font pas. Donc, lorsqu'une liste entre parenthèses est évaluée dans un contexte scalaire, la virgule est traitée comme l'opérateur virgule du C, qui rejette l'argument de gauche, ce qui n'est pas ce que vous voulez.

untie attempted while %d inner references still exist

  • (untie tenté alors que %d références intérieures existent toujours)
  • (W untie) Une copie de l'objet renvoyé par tie (ou par tied) était toujours valide lorsqu'untie a été appelé.

Value of %s can be "0"; test with defined()

  • (La valeur de %s peut valoir "0" ; testez avec defined())
  • (W misc) Dans une expression conditionnelle, vous avez utilisé <HANDLE>, <*> (glob), each ou readdir en tant que valeur booléenne. Chacune de ces constructions peut renvoyer une valeur de "0" ; cela rendrait fausse l'expression conditionnelle, ce qui n'est probablement pas ce que vous désiriez. Quand vous utilisez ces constructions dans des expressions conditionnelles, testez leur valeur avec l'opérateur defined.

Value of CLI symbol "%s" too long

  • (Valeur du symbole de CLI "%s" trop longue)
  • (W misc) Il s'agit d'un avertissement spécifique à VMS. Perl a essayé de lire la valeur d'un élément de %ENV depuis la table de symboles de CLI et a trouvé une chaîne résultante plus longue que 1 024 caractères. La valeur de retour a été tronquée à 1 024 caractères.

Variable "%s" is not imported %s

  • (La variable "%s" n'est pas importée de %s)
  • (F) Alors que use strict est activé, vous vous êtes référés à une variable globale qu'apparemment vous pensiez avoir importée depuis un autre module, car quelque chose d'autre ayant le même nom (habituellement un sous-programme) est exporté par ce module. Cela veut habituellement dire que vous vous êtes trompé de drôle de caractère ($, @, % ou &) devant votre variable.

Variable "%s" may be unavailable

  • (La variable "%s" peut être inaccessible)
  • (W closure) Un sous-programme anonyme intérieur (imbriqué) se trouve dans un sous-programme nommé et encore à l'extérieur se trouve un autre sous-programme ; et le sous-programme anonyme (le plus à l'intérieur) fait référence à une variable lexicale définie dans le sous-programme le plus à l'extérieur. Par exemple :

     
    Sélectionnez
    sub le_plus_exterieur { my $a; sub au_milieu { sub { $a } } }
  • Si le sous-programme anonyme est appelé ou référencé (directement ou indirectement) depuis le sous-programme le plus à l'extérieur, il va partager la variable comme vous pouviez vous y attendre. Mais si le sous-programme anonyme est appelé ou référencé lorsque le sous-programme le plus à l'extérieur est inactif, il verra la valeur de la variable partagée telle qu'elle était avant et pendant le premier appel au sous-programme le plus à l'extérieur, ce qui n'est probablement pas ce que vous voulez.

  • Dans ces circonstances, il vaut habituellement mieux rendre anonyme le sous-programme du milieu anonyme, en utilisant la syntaxe sub {}. Perl possède un support spécifique pour les variables partagées dans les sous-programmes anonymes imbriqués ; un sous-programme nommé entre les deux interfère avec cette fonctionnalité.

Variable "%s" will not stay shared

  • (La variable "%s" ne restera pas partagée)
  • (W closure) Un sous-programme nommé intérieur (imbriqué) fait référence à une variable lexicale définie dans un sous-programme extérieur. Lorsque le sous-programme intérieur est appelé, il verra probablement la valeur de la variable du sous-programme extérieur telle qu'elle était avant et pendant le premier appel au sous-programme extérieur ; dans ce cas, après que le premier appel au sous-programme extérieur est terminé, les sous-programmes intérieur et extérieur ne partageront plus de valeur commune pour la variable. En d'autres termes, la variable ne sera plus partagée.
  • De plus, si le sous-programme extérieur est anonyme et fait référence à une variable lexicale en dehors de lui-même, alors les sous-programmes intérieur et extérieur ne partageront jamais la variable donnée.
  • Le problème peut habituellement être résolu en rendant anonyme le sous-programme intérieur, en utilisant la syntaxe sub {}. Lorsque des sous-programmes anonymes intérieurs, faisant référence à des variables dans des sous-programmes extérieurs, sont appelés ou référencés, ils sont automatiquement reliés à la valeur courante de ces variables.

Variable syntax

  • (Syntaxe de variable)
  • (A) Vous avez lancé accidentellement votre script via csh au lieu de Perl. Vérifiez la ligne #! ou lancez vous-même votre script manuellement dans Perl avec perl nom_script.

Version number must be a constant number

  • (Le numéro de version doit être un nombre constant)
  • (P) La tentative de conversion d'une instruction use Module n.n LISTE vers le bloc BEGIN équivalent a trouvé une incohérence interne dans le numéro de version.

perl: warning: Setting locale failed.

  • (perl : avertissement : Échec avec la configuration des locales)
  • (S) Le message d'avertissement complet ressemblera quelque peu à :

     
    Sélectionnez
    perl: warning: Setting locale failed.
        perl: warning: Please check that your locale settings:
                LC_ALL = "Fr_FR",
                LANG = (unset)
            are supported and installed on your system.
        perl: warning: Falling back to the standard locale ("C").
    N.d.T. :
    Sélectionnez
    perl : avertissement : Échec avec la configuration des locales.
        perl : avertissement : Merci de vérifier que votre configuration des locales :
                LC_ALL = "Fr_FR",
                LANG = (non configuré)
            soit supportée et installée sur votre système.
        perl : avertissement : Retour aux locales standards ("C").
  • (La configuration des locales qui a échoué variera.) Cette erreur indique que Perl a détecté que vous ou votre administrateur système avez configuré les variables du système ainsi nommées, mais Perl n'a pas pu utiliser cette configuration. Ce n'est pas mortel, heureusement : il existe une locale par défaut appelée « C » que Perl peut et va utiliser pour le script puisse ainsi fonctionner. Mais avant que vous résolviez vraiment ce problème, vous allez toutefois avoir le même message d'erreur à chaque fois que vous lancerez Perl. La manière de vraiment résoudre le problème peut être trouvée dans perllocale(1), à la section « Locale Problems ».

Warning: something's wrong

  • (Avertissement : quelque chose s'est mal passé)
  • (W) Vous avez passé à warn une chaîne vide (l'équivalent d'un warn "") ou vous l'avez appelé sans arguments et $_ était vide.

Warning: unable to close filehandle %s properly

  • (Avertissement : incapable de fermer proprement le handle de fichier %s)
  • (S) Le close implicite effectué par un open a reçu une indication d'erreur sur le close. Cela indique habituellement que votre système de fichier a épuisé l'espace disque disponible.

Warning: Use of "%s" without parentheses is ambiguous

  • (Avertissement : L'utilisation de "%s" sans parenthèses est ambiguë)
  • (S ambiguous) Vous avez écrit un opérateur unaire suivi par quelque chose ressemblant à un opérateur binaire, mais pouvant également être interprété comme un terme ou un opérateur unaire. Par exemple, si vous savez que la fonction rand a un argument par défaut valant 1.0 et que vous écrivez :

     
    Sélectionnez
    rand + 5;
  • vous pouvez pensez que vous avez écrit la même chose que :

     
    Sélectionnez
    rand() + 5;
  • alors qu'en fait vous avez obtenu :

     
    Sélectionnez
    rand(+5);
  • Donc mettez des parenthèses pour dire ce que vous voulez vraiment dire.

write() on closed filehandle

  • (write() sur un handle de fichier fermé)
  • (W closed) Le handle de fichier dans lequel vous écrivez s'est retrouvé fermé un moment auparavant. Vérifiez le flux logique de votre programme.

X outside of string

  • (X en dehors d'une chaîne)
  • (F) Vous aviez un canevas pour pack spécifiant une position relative avant le début de la chaîne en train d'être dépaqueté.

x outside of string

  • (x en dehors d'une chaîne)
  • (F) Vous aviez un canevas pour pack spécifiant une position relative après la fin de la chaîne en train d'être dépaqueté.

Xsub "%s" called in sort

  • (Xsub "%s" appelé dans un sort)
  • (F) L'utilisation d'un sous-programme externe pour la comparaison d'un sort n'est pas encore supportée.

Xsub called in sort

  • (Xsub "%s" appelé dans un sort)
  • (F) L'utilisation d'un sous-programme externe pour la comparaison d'un sort n'est pas encore supportée.

You can't use -l on a filehandle

  • (Vous ne pouvez pas utiliser -l sur un handle de fichier)
  • (F) Un handle de fichier représente un fichier ouvert et lorsque vous avez ouvert le fichier, il avait déjà passé tous les liens symboliques que vous essayez vraisemblablement de rechercher. Utilisez plutôt un nom de fichier.

YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!

  • (VOUS N'AVEZ TOUJOURS PAS DÉSACTIVÉ LES SCRIPTS SET-ID DANS LE NOYAU !)
  • (F) Et vous ne le ferez probablement jamais, car vous n'avez pas les sources du noyau et probablement que votre fabricant se moque éperdument de ce que vous voulez. La meilleure solution est de mettre une surcouche setuid en C autour de votre script en utilisant le script wrapsuid situé dans le répertoire eg de la distribution Perl.

You need to quote "%s"

  • (Vous devez protéger "%s" avec des guillemets ou des apostrophes)
  • (W syntax) Vous avez affecté un mot simple comme nom d'un gestionnaire de signaux. Malheureusement, vous avez déjà un sous-programme avec ce nom, ce qui veut dire que Perl 5 essayera d'appeler ce sous-programme lorsque l'affectation sera exécutée, ce qui n'est probablement pas ce que vous voulez. (Si c'est bien ce que vous voulez, mettez une & devant.)

précédentsommairesuivant
Bien que beaucoup de moteurs d'expressions régulières ne supportent que jusqu'à neuf références arrière, Perl ne possède pas de telle limite ; ainsi si vous écrivez $768, Perl n'en aura cure, bien que ceux qui maintiennent votre code puissent tiquer si vous employez autant de parenthèses dans vos expressions régulières.
Parfois, les fonctions étroitement liées sont regroupées ensemble dans les pages man du système, nous respectons donc ici cette organisation. Pour trouver par exemple la description de endpwent, vous devrez cherchez sous getpwent.
Plus précisément, vous serez capable d'employer les disciplines pour ceci, mais nous n'avons pas achevé leur implémentation au moment où ces lignes sont écrites.
Seules les personnes qui ont des intentions louables sont autorisées à faire ceci.
Cela veut dire que si elle ne trouve pas l'étiquette dans la routine courante, elle cherche dans celles qui l'ont appelée, rendant ainsi la maintenance du programme quasiment impossible.
Les euphémismes sont réputés être amusants, alors nous avons pensé en essayer un ici.
date(1) affiche le fuseau horaire, alors que scalar localtime ne le fait pas.
Ou vous pouvez la considérer comme la porte de sortie de la commande des formes à trois arguments ci-dessus.
Cela ne fonctionne pas (pour le moment) avec les objets d'entrée/sortie sur les références de typeglobs par autovivification, mais vous pouvez toujours employer fileno pour aller chercher le descripteur de fichier et le dupliquer.
STDOUT n'est donc pas vraiment le handle de fichier par défaut pour print. Il est en fait le handle de fichier par défaut du défaut.
Knuth, D.E. The Art of Computer Programming, Seminumerial Algorithms, vol. 2, 3rd ed. (Reading, Mss.: Addison-Wesley, 1997). ISBN 0-201-89684-2.
N.d.T. : Perl Power Tools: The Unix Reconstruction Project, un projet dont le but avoué est : « de manière assez simple, de réimplémenter le jeu de commandes classiques Unix en Perl pur, et de nous amuser autant que possible en faisant cela ».
N.d.T. : les anglophones ont la chance de dire timeout, ce qui évite toute confusion dans les unités de temps !
N.d.T. : unité de profondeur égale à 1828 mm.
N.d.T. : en anglais « sin » signifie « péché ».
N.d.T. : du nom de l'illustre coauteur des précédentes éditions de cet ouvrage : Randal L. Schwartz.
Un contexte scalaire entraîne également le fait que split écrive son résultat dans @_, mais cet usage est déprécié.
Mise à part pour les nombres à virgule flottante, et même dans ce cas, seulement les modificateurs standards sont autorisés.
Bien qu'il le supporte via $(.
En fait, les méthodes de IO::File ou IO::Handle.
C'est-à-dire /bin/sh par définition, ou tout ce qui a un sens sur votre plate-forme, mais pas le shell que l'utilisateur utilise à ce moment.
Ou des soirées cuir et chaînes.
Que l'on appelle aussi « epoch », origine — à ne pas confondre avec l'« épopée », qui se rapporte à la conception d'UNIX. (D'autres systèmes d'exploitation ont une origine différente, pour ne pas parler de leur épopée.)
En fait, sous un système de fichier POSIX, elle supprime les entrées de répertoire (fichiers) qui se réfèrent aux véritables fichiers. Comme un fichier peut être référencé (lié) depuis plus d'un répertoire, le fichier lui-même n'est pas détruit avant que la dernière référence pointant sur lui ne soit effacée.
N.d.T. : Littéralement : « Avertissement : Il y a quelque chose de mauvais ».
Nous ne voulons pas dire par là des scripts Perls. Nous voulons dire des « scripts » comme dans certains styles particuliers de lettres écrites, comme le romain ou le grec ou le cyrillique. Malheureusement, « script » est le terme technique pour cela et nous n'avons pas beaucoup de chance de persuader le Consortium Unicode d'adopter un terme différent.
Implémentée comme un sous-programme sans argument et renvoyant toujours la même constante.
N.d.T. : signe qui donne à un caractère de l'alphabet une valeur spéciale.
En l'absence de blocs BEGIN, bien entendu.
Pourvu que vous ayez la bibliothèque installée sur votre système. Sinon, vous pouvez la compiler et l'installer assez facilement.
Ou aller chercher les versions PPT si votre plate-forme est un défi pour ces outils. N.d.T. : Perl Power Tools : The Unix Reconstruction Project, un projet dont le but avoué est : « Notre objectif est, de manière assez simple, de réimplémenter le jeu de commandes classiques Unix en Perl pur, et de nous amuser autant que possible en faisant cela. » .
À cause des restrictions de syntaxe dans l'opérateur interne glob, il se peut que vous deviez appeler la fonction en tant que bsd_glob si vous voulez lui passer le second argument.
Bien que techniquement, le slash aussi — du moins aussi longtemps que cela concerne les noyaux et les appels systèmes ; les commandes shell sont remarquablement moins bien éclairées.
Comme il charge beaucoup de code, ce module vous coûte environ un mégaoctet en mémoire.

Licence Creative Commons
Le contenu de cet article est rédigé par Larry Wall, Tom Christiansen et Jon Orwant et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Pas de Modification 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2018 Developpez.com.