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;
    }