perlfunc - Fonctions Perl prédéfinies
Les fonctions de cette section peuvent être utilisées en tant que termes dans
une expression. Elles se séparent en deux catégories principales : les
opérateurs de listes et les opérateurs unaires nommés. Ceux-ci diffèrent dans
leurs relations de priorité avec la virgule qui les suit. (Cf. la table de
priorité dans la page de manuel perlop.) Les opérateurs de liste prennent plusieurs
arguments alors que les opérateurs unaires n'en prennent jamais plus d'un. Une
virgule termine alors l'argument d'un opérateur unaire mais sépare les
arguments d'un opérateur de liste. Un opérateur unaire fournit en général un
contexte scalaire à son argument, alors qu'un opérateur de liste fournit un
contexte, soit scalaire, soit de liste, pour ses arguments. S'il propose les
deux, les arguments scalaires seront les premiers et la liste d'arguments
suivra. (Notez qu'il ne peut y avoir qu'une seule liste d'arguments.) Par
exemple, splice() a trois arguments scalaires suivis d'une liste alors que
gethostbyname() a quatre arguments scalaires.
Dans la description syntaxique qui suit, les opérateurs de liste qui attendent une liste (et fournissent un contexte de liste pour les éléments de cette liste) ont pour argument LISTE. Une telle liste peut être constituée de toute combinaison de valeurs d'arguments scalaires ou de listes ; les valeurs de listes seront incluses dans la liste comme si chaque élément individuel était interpolé à cet emplacement de la liste, formant ainsi la valeur d'une longue liste unidimensionnelle. Les éléments de LISTE doivent être séparés par des virgules.
Toute fonction de la liste ci-dessous peut être utilisée avec ou sans parenthèses autour de ses arguments. (Les descriptions syntaxiques les omettent) Si vous utilisez les parenthèses, la simple (mais parfois surprenante) règle est la suivante : ça RESSEMBLE à une fonction, donc c'EST une fonction, et la priorité importe peu. Sinon, c'est un opérateur de liste ou un opérateur unaire et la priorité a son importance. Les espaces entre la fonction et les parenthèses ne comptent pas, vous devez donc faire parfois très attention :
print 1+2+4; # affiche 7.
print(1+2) + 4; # affiche 3.
print (1+2)+4; # affiche aussi 3 !
print +(1+2)+4; # affiche 7.
print ((1+2)+4); # affiche 7.
Si vous exécutez Perl avec l'option -w, vous pourrez en être averti. Par exemple, la troisième ligne ci-dessus génère :
print (...) interpreted as function at - line 1.
Useless use of integer addition in void context at - line 1.
Quelques rares fonctions ne prennent aucun argument et ne sont donc ni des
opérateurs unaires ni des opérateurs de liste. Cela inclut des fonctions
telles que time et endpwent. Par exemple, time+86_400 signifie
toujours time() + 86_400.
Pour les fonctions qui peuvent être utilisées dans un contexte scalaire ou de liste, une erreur non fatale est généralement indiquée dans un contexte scalaire en retournant la valeur indéfinie, et dans un contexte de liste en retournant la liste nulle.
Rappelez-vous de l'importante règle suivante : il n'y a aucune règle qui lie le comportement d'une expression dans un contexte de liste à son comportement dans un contexte scalaire, et réciproquement. Cela peut générer deux résultats complètement différents. Chaque opérateur et chaque fonction choisit le type de valeur qui semble le plus approprié de retourner dans un contexte scalaire. Certains opérateurs retournent la longueur de la liste qui aurait été retournée dans un contexte de liste. D'autres opérateurs retournent la première valeur. D'autres encore retournent la dernière valeur. D'autres enfin retournent le nombre d'opérations réussies. En général, ils font ce que vous souhaitez, à moins que vous ne vouliez de la consistance.
Un tableau nommé en contexte scalaire est assez différent de ce qui
apparaîtrait au premier coup d'oeil comme une liste dans un contexte
scalaire. Vous ne pouvez pas transformer une liste comme (1,2,3) dans un
contexte scalaire, car le compilateur connaît le contexte à la compilation. Il
générerait ici l'opérateur scalaire virgule, et non pas la version
construction de liste de la virgule. Ce qui signifie que ça n'a jamais été
considéré comme une liste avec laquelle travailler.
En général, les fonctions en Perl qui encapsulent les appels système du même
nom (comme chown(2), fork(2), closedir(2), etc.) retournent toutes vrai quand
elles réussissent et undef sinon, comme c'est souvent mentionné
ci-dessous. C'est différent des interfaces C qui retournent -1 en cas
d'erreur. Les exceptions à cette règle sont wait, waitpid() et
syscall(). Les appels système positionnent aussi la variable spéciale $!
en cas d'erreur. Les autres fonctions ne le font pas, sauf de manière
accidentelle.
Voici les fonctions Perl (y compris ce qui ressemble à des fonctions, comme certains mots-clés et les opérateurs nommés) triées par catégorie. Certaines fonctions apparaissent dans plusieurs catégories à la fois.
chomp, chop, chr, crypt, hex, index, lc, lcfirst,
length, oct, ord, pack, q/CHAINE/, qq/CHAINE/, reverse,
rindex, sprintf, substr, tr///, uc, ucfirst, y///
m//, pos, quotemeta, s///, split, study, qr//
abs, atan2, cos, exp, hex, int, log, oct, rand,
sin, sqrt, srand
pop, push, shift, splice, unshift
grep, join, map, qw/CHAINE/, reverse, sort, unpack
delete, each, exists, keys, values
binmode, close, closedir, dbmclose, dbmopen, die, eof,
fileno, flock, format, getc, print, printf, read,
readdir, rewinddir, seek, seekdir, select, syscall,
sysread, sysseek, syswrite, tell, telldir, truncate,
warn, write
pack, read, syscall, sysread, syswrite, unpack, vec
-X, chdir, chmod, chown, chroot, fcntl, glob,
ioctl, link, lstat, mkdir, open, opendir, readlink,
rename, rmdir, stat, symlink, sysopen, umask, unlink,
utime
caller, continue, die, do, dump, eval, exit,
goto, last, next, redo, return, sub, wantarray
caller, import, local, my, our, package, use
defined, dump, eval, formline, local, my, our, reset,
scalar, undef, wantarray
alarm, exec, fork, getpgrp, getppid, getpriority, kill,
pipe, qx/CHAINE/, setpgrp, setpriority, sleep, system,
times, wait, waitpid
do, import, no, package, require, use
bless, dbmclose, dbmopen, package, ref, tie, tied,
untie, use
accept, bind, connect, getpeername, getsockname,
getsockopt, listen, recv, send, setsockopt, shutdown,
socket, socketpair
msgctl, msgget, msgrcv, msgsnd, semctl, semget, semop,
shmctl, shmget, shmread, shmwrite
endgrent, endhostent, endnetent, endpwent, getgrent,
getgrgid, getgrnam, getlogin, getpwent, getpwnam,
getpwuid, setgrent, setpwent
endprotoent, endservent, gethostbyaddr, gethostbyname,
gethostent, getnetbyaddr, getnetbyname, getnetent,
getprotobyname, getprotobynumber, getprotoent,
getservbyname, getservbyport, getservent, sethostent,
setnetent, setprotoent, setservent
gmtime, localtime, time, times
abs, bless, chomp, chr, exists, formline, glob,
import, lc, lcfirst, map, my, no, our, prototype,
qx, qw, readline, readpipe, ref, sub*, sysopen, tie,
tied, uc, ucfirst, untie, use
* - sub était un mot-clé dans perl4, mais dans perl5 c'est un
opérateur qui peut être utilisé au sein d'expressions.
dbmclose, dbmopen
Perl est né sur Unix et peut, par conséquent, accéder à tous les appels systèmes Unix courants. Dans des environnements non-Unix, les fonctionnalités de certains appels systèmes Unix peuvent manquer ou différer sur certains détails. Les fonctions Perl affectées par cela sont :
-X, binmode, chmod, chown, chroot, crypt,
dbmclose, dbmopen, dump, endgrent, endhostent,
endnetent, endprotoent, endpwent, endservent, exec,
fcntl, flock, fork, getgrent, getgrgid, gethostent,
getlogin, getnetbyaddr, getnetbyname, getnetent,
getppid, getpgrp, getpriority, getprotobynumber,
getprotoent, getpwent, getpwnam, getpwuid,
getservbyport, getservent, getsockopt, glob, ioctl,
kill, link, lstat, msgctl, msgget, msgrcv,
msgsnd, open, pipe, readlink, rename, select, semctl,
semget, semop, setgrent, sethostent, setnetent,
setpgrp, setpriority, setprotoent, setpwent,
setservent, setsockopt, shmctl, shmget, shmread,
shmwrite, socket, socketpair, stat, symlink, syscall,
sysopen, system, times, truncate, umask, unlink,
utime, wait, waitpid
Pour de plus amples détails sur la portabilité de ces fonctions, voir la page de manuel perlport et toutes les documentations disponibles spécifiques à la plate-forme considérée.
$_, sauf
-t qui teste STDIN. Sauf indication contraire, il retourne 1 pour VRAI
et '' pour FAUX, ou la valeur indéfinie (undef) si le fichier n'existe
pas. Malgré leurs noms originaux, leur priorité est la même que celle de tout
autre opérateur unaire nommé et l'argument peut-être mis de même entre
parenthèses. L'opérateur peut être :
-r Le fichier est en lecture par le uid/gid effectif.
-w Le fichier est en écriture par le uid/gid effectif.
-x Le fichier est exécutable par le uid/gid effectif.
-o Le fichier appartient au uid effectif.
-R Le fichier est en lecture par le uid/gid réel.
-W Le fichier est en écriture par le uid/gid réel.
-X Le fichier est exécutable par le uid/gid réel.
-O Le fichier appartient au uid réel.
-e Le fichier existe.
-z Le fichier a une taille nulle (il est vide).
-s Le fichier n'a pas une taille nulle (retourne sa taille en octets).
-f Le fichier est un fichier normal.
-d Le fichier est un répertoire.
-l Le fichier est un lien symbolique.
-p Le fichier est un tube nommée (FIFO), ou le descripteur est un pipe.
-S Le fichier est une socket.
-b Le fichier est un fichier blocs spécial.
-c Le fichier est un fichier caractères spécial.
-t Le fichier est ouvert sur un tty.
-u Le fichier a le bit setuid positionné.
-g Le fichier a le bit setgid positionné.
-k Le fichier a le sticky bit positionné.
-T Le fichier est un fichier texte ASCII (via une heuristique).
-B Le fichier est un fichier binaire (le contraire de -T).
-M La date de démarrage du script moins la date de dernière
modification du fichier (exprimé en jours).
-A Idem pour le dernier accès au fichier.
-C Idem pour le dernier changement de l'inode du fichier
(Unix peut avoir un comportement différent des autres systèmes).
Exemple :
while (<>) {
chomp;
next unless -f $_; # ignore les fichiers spéciaux
#...
}
L'interprétation des opérateurs de permission sur le fichier -r, -R,
-w, -W, -x, et -X est uniquement basée sur le mode du fichier et
les uids/gids de l'utilisateur. En fait, il peut y avoir d'autres raisons pour
lesquelles vous ne pouvez pas lire, écrire ou exécuter le fichier. Par
exemple, le contrôle d'accès aux systèmes de fichiers réseau (NFS), les listes
de contrôles d'accès (ACL), les systèmes de fichiers en lecture seule et les
formats d'exécutable non reconnus.
Notez aussi que, pour le super-utilisateur, -r, -R, -w, et -W
retournent toujours 1, et -x ainsi que -X retournent 1 si l'un des
bits d'exécution est positionné dans le mode. Les scripts exécutés par le
super-utilisateur peuvent donc nécessiter un appel stat() pour déterminer
exactement les droits du fichier ou alors effectuer un changement temporaire
d'uid.
Si vous utilisez les ACL (listes de contrôles d'accès), il existe un pragma
appelé filetest qui peut produire des résultats plus précis que les
informations minimales des bits de permissions fournies par stat(). Lorsque
vous faites use filetest 'access', les tests sur fichiers susnommés
utiliseront les appels systèmes de la famille access(). Notez aussi que dans
ce cas, les tests -x et -X peuvent retourner VRAI même si aucun bit
d'exécution n'est positionné (que ce soit les bits normaux ou ceux des
ACLs). Ce comportement étrange est dû à la définition des appels systèmes
sous-jacents. Lisez la documentation du pragma filetest pour de plus amples
informations.
Notez que -s/a/b/ n'effectue pas une substitution négative. Toutefois,
écrire -exp($foo) fonctionne toujours comme prévu -- seule une lettre
isolée après un tiret est interprétée comme un test de fichier.
Les tests -T et -B fonctionnent de la manière suivante. Le premier bloc
du fichier est examiné, à la recherche de caractères spéciaux tels que des
codes de contrôle ou des octets avec un bit de poids fort. Si trop de
caractères spéciaux (> 30 %) sont rencontrés, c'est un fichier -B,
sinon c'est un fichier -T. De plus, tout fichier contenant un octet nul
dans le premier bloc est considéré comme binaire. Si -T ou -B est
utilisé sur un descripteur de fichier, le tampon stdio courant est examiné à
la place du premier bloc. -T et -B retournent tous les deux VRAI sur un
fichier nul, ou une fin de fichier s'il s'agit d'un descripteur. Comme vous
devez lire un fichier pour effectuer le test -T, la plupart du temps, vous
devriez d'abord utiliser un -f sur le fichier, comme dans next unless -f
$file && -T $file.
Si le descripteur spécial, constitué d'un seul underscore (N.d.T. :
caractère souligné), est fourni comme argument d'un test de fichier (ou aux
opérateurs stat() et lstat()), alors c'est la structure stat du dernier
fichier traité par un test (ou opérateur) qui est utilisée, épargnant ainsi un
appel système. (Ceci ne fonctionne pas avec -t et n'oubliez pas que lstat()
et -l laisseront dans la structure stat des informations liées au fichier
symbolique et non au fichier réel.) (Notez aussi que si des informations
issues d'un appel à lstat étaient dans le buffer stat alors -T et -B
les remplaceront par le résultat de stat _.) Exemple :
print "Can do.\n" if -r $a || -w _ || -x _;
stat($filename);
print "Readable\n" if -r _;
print "Writable\n" if -w _;
print "Executable\n" if -x _;
print "Setuid\n" if -u _;
print "Setgid\n" if -g _;
print "Sticky\n" if -k _;
print "Text\n" if -T _;
print "Binary\n" if -B _;
$_.
Sur les systèmes qui supportent le drapeau fermeture-à-l-exécution (close-on-exec) sur les fichiers, ce drapeau sera positionné pour de nouveaux descripteurs de fichier en fonction de la valeur de $^F. Voir « $^F » dans la page de manuel perlvar.
$_ est utilisée. (Sur certaines machines, malheureusement, le temps écoulé
peut être jusqu'à une seconde de plus ou de moins que celui spécifié, en
fonction de la façon dont les secondes sont comptées. De plus, la partage du
temps entre les différents processus peut entraîner un retard supplémentaire.)
Il n'est pas possible d'activer plusieurs décomptes temporels à la
fois. Chaque appel annule le décompte précédent. La valeur 0 peut être
fournie pour annuler le décompte précédent sans en créer un nouveau. La valeur
retournée est le temps restant de décompte précédent.
Pour des délais d'une précision inférieure à la seconde, vous pouvez utiliser
soit la version Perl à quatre paramètres de select() en laissant les trois
premiers indéfinis soit l'interface syscall() de Perl pour accéder à
setitimer(2) si votre système le supporte. Le module Time::HiRes (qui fait
partie de Perl depuis la version 5.8 ou disponible sur CPAN sinon) peut aussi
s'avérer utile.
C'est souvent une erreur de mélanger des appels à alarm() avec des appels à
sleep() (sleep peut-être implémenté via des appels internes à alarm
sur votre système.)
Si vous souhaitez utiliser alarm() pour contrôler la durée d'un appel
système, il vous faut utiliser le couple eval()/die(). Vous ne pouvez
pas compter sur l'alarme qui déclenche l'échec de l'appel système avec $!
positionné à EINTR car Perl met en place des descripteurs de signaux pour
redémarrer ces appels sur certains systèmes. Utiliser eval()/die()
fonctionne toujours sous réserve de l'avertissement signalé dans
« Signaux » dans la page de manuel perlipc.
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # N.B. : \n obligatoire
alarm $timeout;
$nread = sysread SOCKET, $buffer, $size;
alarm 0;
};
if ($@) {
die unless $@ eq "alarm\n"; # propage des erreurs inattendues
# délai dépassé : time out
}
else {
# délai non dépassé
}
Pour l'opération tangente, vous pouvez utiliser la fonction
POSIX::tan() ou la relation habituelle :
sub tan { sin($_[0]) / cos($_[0]) }
pack()) du type approprié pour la socket. Voir les exemples de
« Sockets : communication client/serveur » dans la page de manuel perlipc.
undef en cas
d'échec.
Si FILTRE est omis ou s'il vaut :raw, le DESCRIPTEUR est positionné pour
passer des données binaires. Cela inclut la désactivation d'une éventuelle
traduction des CRLF et passe en mode octets (à opposer à des caractères
Unicode). Notez bien que, en dépit de ce qui est dit dans ``Programming
Perl'' (le Camel) ou ailleurs, :raw n'est pas l'inverse de :crlf
-- toute autre filtre (FILTRE ou LAYER en anglais) qui pourrait modifier la
nature binaire du flot est aussi désactivée. Voir PerlIO, la page de manuel perlrun et
tout ce qui est dit de la variable d'environnement PERLIO.
Le paramètre FILTRE de la fonction binmode() est appelé ``DISCIPLINE'' dans ``Programming Perl, 3rd Edition''. Mais, depuis la publication de ce livre connu sous le nom de ``Camel III'', un consensus pour le nommage de ce paramètre est passé de ``discipline'' à ``filtre'' (layer en anglais). Toute la documentation de cette version de Perl se réfère donc maintenant à ``layer'' plutôt qu'à ``discipline''. Revenons maintenant à la documentation...
Sur certains systèmes (en général les systèmes DOS et ceux basés sur Windows),
binmode() est nécessaire lorsque vous ne travaillez pas avec des fichiers
texte. Pour assurer la portabilité, c'est une bonne idée de toujours
l'utiliser lorsque c'est approprié et de ne jamais l'utiliser dans les autres
cas.
En d'autres termes : indépendamment de la plate-forme, utilisez binmode() sur
les fichier binaires et n'utilisez pas binmode() sur les fichiers textes.
Si FILTRE est présent, il doit être une seule chaîne de caractères mais il
peut contenir plusieurs directives. Ces directives modifient le comportement
du DESCRIPTEUR. L'utilisation de FILTRE via binmode() sur des fichiers texte a
un sens.
Pour marquer un DESCRIPTEUR comme UTF-8, utilisez :utf8.
Les directives comme :bytes, :crlf, :utf8 ou de la forme :... sont
appelées des filtres I/O (filtres d'entrée/sortie). La directive open
peut être utilisée pour spécifier les filtres d'I/O par défaut. Voir open.
En général, binmode() devrait être appelé après open() et avant n'importe
quelle opération d'entrée/sortie. L'appel à binmode() videra tous les tampons
de données en attente de sortie (ou d'entrée). La seule exception est le
filtre :encoding qui change l'encodage par défaut du DESCRIPTEUR. Voir
open. L'appel au filtre :encoding est parfois nécessaire en cours de
flot : il ne vide pas les tampons.
Le système d'exploitation, les pilotes de périphériques, les bibliothèques C
et l'interpréteur de Perl coopèrent afin de permettre au programmeur de
considérer une fin de ligne comme un seul caractère (\n) et cela,
indépendamment de sa représentation externe. Sur la plupart des systèmes
d'exploitation, la représentation utilisée par les fichiers textes natifs
correspond à la représentation interne mais sur certaines plates-formes la
représentation externe de \n est constituée de plus d'un caractère.
Mac OS, toutes les variantes d'UNIX et les Stream_LF de VMS utilisent un seul
caractère pour représenter une fin de ligne dans leur représentation externe
des textes (même si ce caractère unique est un RETOUR CHARIOT sur Mac OS et un
SAUT DE LIGNE sur Unix et dans la plupart des fichiers VMS). Sur d'autres
systèmes tels que VMS, MS-DOS et les différentes versions de MS-Windows, votre
programme voit un \n comme un simple \cJ mais ce qui est réellement
stocké dans les fichiers textes est le couple de caractères \cM\cJ. Cela
signifie que, si vous n'utilisez pas binmode() sur ces systèmes, les séquences
\cM\cJ sur disque seront converties en \n en entrée et que tous les
\n produits par votre programme seront reconvertis en \cM\cJ à la
sortie. C'est ce que vous voulez pour les fichiers textes mais cela peut être
désastreux pour un fichier binaire.
Autre conséquence de l'utilisation de binmode() (sur certains systèmes) : les
marqueurs spéciaux de fin de fichiers seront vus comme faisant partie du flux
de données. Pour les systèmes de la famille Microsoft, cela signifie que, si
vos données binaires contiennent un \cZ, le système d'entrée/sortie le
considérera comme une fin de fichier à moins que vous n'utilisiez binmode().
binmode() est important non seulement pour les opérations readline() et
print() mais aussi lorsque vous utilisez read(), seek(), sysread(), syswrite()
et tell() (voir la page de manuel perlport pour plus d'informations). Voir aussi $/ et
$\ dans la page de manuel perlvar pour savoir comment fixer manuellement les séquences de
fin de lignes en entrée et en sortie.
bless() est souvent la dernière instruction d'un constructeur, cette
fonction retourne la référence elle-même. Utilisez toujours la version à deux
arguments si la fonction effectuant la ``bénédiction'' bless() peut être
héritée par une classe dérivée. Cf. la page de manuel perltoot et la page de manuel perlobj pour de plus
amples informations sur la bénédiction (et les bénédictions) d'objets.
Ne blessez des objets qu'avec des NOMCLASSEs mélangeant des majuscules et des minuscules. Les espaces de nommages entièrement en minuscule sont réservés pour les directives (pragmas) Perl. Les types prédéfinis utilisent les noms entièrement en majuscule. Donc, pour éviter toute confusion, vous devez éviter ces deux types de nommage. Soyez sûr que NOMCLASSE est une valeur vraie.
eval() ou un
require(), et retourne la valeur indéfinie (undef) sinon. En contexte de
liste, retourne
($package, $filename, $line) = caller;
Avec EXPR, il retourne des informations supplémentaires que le débogueur utilise pour afficher un historique de la pile. La valeur de EXPR donne le nombre de contextes d'appels à examiner au-dessus de celui en cours.
($package, $filename, $line, $subroutine, $hasargs,
$wantarray, $evaltext, $is_require, $hints, $bitmask) = caller($i);
Ici, $subroutine peut être "(eval)" si le cadre n'est pas un appel de
routine mais un eval(). Dans un tel cas, les éléments supplémentaires
$evaltext et $is_require sont positionnés : $is_require est vrai
si le contexte est créé par un require ou un use, $evaltext contient
le texte de l'instruction eval EXPR. En particulier, pour une instruction
eval BLOC, $filename vaut "(eval)" mais $evaltext est
indéfini. (Notez aussi que chaque instruction use crée un contexte
require à l'intérieur d'un contexte eval EXPR.) $subroutine peut
aussi être (unknown) si cette subroutine particulière a disparu de la table
des symboles. $hasargs est vrai si une nouvelle instance de @_ a été
créé pour ce contexte. Les valeurs de $hints et de $bitmask risquent de
changer d'une version de Perl à une autre. Elles n'ont donc aucun intérêt pour
une utilisation externe.
De plus, s'il est appelé depuis le paquetage DB, caller retourne plus de
détails : il affecte à la liste de variables @DB::args les arguments
avec lesquels la routine a été appelée.
Prenez garde à l'optimiseur qui a pu optimiser des contextes d'appel avant que
caller() ait une chance de récupérer les informations. Ce qui signifie que
caller(N) pourrait ne pas retourner les informations concernant le contexte
d'appel que vous attendez, pour N > 1. En particulier, @DB::args
peut contenir des informations relatives à un appel précédent de caller().
$ENV{HOME} si elle est
définie ; sinon, c'est le répertoire spécifié par la variable
$ENV{LOGDIR} qui est utilisé. (Sous VMS, la variable $ENV{SYS$LOGIN} est
aussi regardée et utilisée si elle est définie.) Si aucune de ces variables
n'est définie, chdir seul ne fait rien. Retourne VRAI en cas de succès,
FAUX sinon. Cf. exemple de die().
0644 est correct, mais pas
'0644'. Retourne le nombre de fichiers dont les permissions ont été
changées avec succès. Voir aussi « oct », si vous ne disposez que d'une chaîne
de chiffres.
$cnt = chmod 0755, 'foo', 'bar';
chmod 0755, @executables;
$mode = '0644'; chmod $mode, 'foo'; # !!! fixe le mode à
# --w----r-T
$mode = '0644'; chmod oct($mode), 'foo'; # ceci est mieux
$mode = 0644; chmod $mode, 'foo'; # cela est le meilleur
Vous pouvez aussi importer les constantes symboliques S_I* du module
Fcntl :
use Fcntl ':mode';
chmod S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, @executables;
# Identique au chmod 0755 de l'exemple précédent.
$/ (connue aussi sous le nom de $INPUT_RECORD_SEPARATOR
dans le module English). Elle retourne le nombre total de caractères
effacés de tous ses arguments. Elle est souvent utilisée pour effacer le saut
de ligne de la fin d'une entrée quand vous vous souciez que l'enregistrement
final pourrait ne pas avoir ce saut de ligne. En mode paragraphe ($/ = ""),
elle efface tous les sauts de ligne à la fin de la chaîne de caractères. En
mode «slurp» ($/ = undef) ou en mode enregistrement de taille fixe ($/
est une référence vers un entier ou similaire, voir la page de manuel perlvar) chomp() ne
supprime rien du tout. Si VARIABLE est omis, elle tronque $_. Exemple :
while (<>) {
chomp; # évite le \n du dernier champ
@array = split(/:/);
# ...
}
Vous pouvez en fait tronquer tout ce qui est une lvalue, y compris les affectations :
chomp($cwd = `pwd`);
chomp($answer = <STDIN>);
Si vous tronquez une liste, chaque élément est tronqué et le nombre total de caractères effacés est retourné.
Notez que les parenthèses sont nécessaires lorsque vous voulez ``chomp''-er
quelque chose qui n'est pas une simple variable. C'est parce que chomp $cwd
= `pwd`; est interprété comme (chomp $cwd) = `pwd`; plutôt que comme
chomp( $cwd = `pwd` );. De même dans le cas de chomp $a, $b qui est
interprété comme chomp($a), $b plutôt que comme chomp($a, $b).
s/\n// étant donné qu'il ne scanne ni ne copie la chaîne. Si
VARIABLE est omis, tronque $_. Exemple :
while (<>) {
chop; # évite \n du dernier champ
@array = split(/:/);
#...
}
Vous pouvez en fait tronquer tout ce qui est une lvalue, y compris les affectations :
chop($cwd = `pwd`);
chop($answer = <STDIN>);
Si vous tronquez une liste, chaque élément est tronqué. Seul la valeur
du dernier chop() est retournée.
Notez que chop() retourne le dernier caractère. Pour retourner tout
sauf le dernier caractère, utilisez substr($string, 0, -1).
Voir aussi « chomp ».
$cnt = chown $uid, $gid, 'foo', 'bar';
chown $uid, $gid, @filenames;
Voici un exemple qui cherche les uid non numériques dans le fichier de mots de passe :
print "User: ";
chop($user = <STDIN>);
print "Files: ";
chop($pattern = <STDIN>);
($login,$pass,$uid,$gid) = getpwnam($user)
or die "$user not in passwd file";
@ary = glob($pattern); # expansion des noms de fichiers
chown $uid, $gid, @ary;
Sur la plupart des systèmes, vous n'êtes pas autorisé à changer le propriétaire d'un fichier à moins d'être le super-utilisateur, même si avez la possibilité de changer un groupe en l'un de vos groupes secondaires. Sur les systèmes non sécurisés, ces restrictions peuvent être moindres, mais ceci n'est pas une hypothèse portable. Sur les systèmes POSIX, vous pouvez détecter cette condition de la manière suivante :
use POSIX qw(sysconf _PC_CHOWN_RESTRICTED);
$can_chown_giveaway = not sysconf(_PC_CHOWN_RESTRICTED);
chr(65) est "A" en ASCII ou Unicode et chr(0x263a) est un
visage réjoui en Unicode. Notez que les caractères de 127 à 255 (inclu) ne
sont pas par défaut encodés en Unicode pour des raisons de compatibilités
(voir encoding).
Pour la fonction réciproque, utilisez « ord ». Voir perlunicode et encoding pour en savoir plus sur Unicode.
Si NOMBRE est omis, utilise $_.
"/" utilisés par votre processus et
ses enfants. (Ceci n'affecte pas le répertoire courant qui reste
inchangé.) Pour des raisons de sécurité, cet appel est restreint au
super-utilisateur. Si FICHIER est omis, effectue un chroot() sur $_.
Vous n'avez pas à fermer le DESCRIPTEUR si vous allez immédiatement refaire un
open() sur celui-ci, car open() le fermera pour vous. (voir open().)
Toutefois, un close() explicite sur un fichier d'entrée réinitialise le
compteur de lignes ($.) alors que la fermeture implicite par un open() ne
le fait pas.
Si le descripteur vient d'un tube ouvert, close() va de plus retourner FAUX
si un des autres appels système impliqués échoue ou si le programme se
termine avec un statut non nul. (Si le seul problème rencontré est une
terminaison de programme non nulle, $! sera à 0.) De même, la fermeture
d'un tube attend que le programme exécuté sur le tube soit achevé, au cas où
vous souhaiteriez voir la sortie du tube après coup, et positionne
implicitement la valeur du statut de sortie de la commande dans $?.
La fermeture prématurée d'une extrémité de lecture d'un tube (c'est-à-dire avant que le processus qui écrit à l'autre extrémité l'ait fermé) aura pour conséquence l'envoi d'un signal SIGPIPE au processus écrivain. Si l'autre extrémité n'est pas prévue pour gérer cela, soyez sûr d'avoir lu toutes les données avant de fermer le tube.
Exemple :
open(OUTPUT, '|sort >foo') # tube vers sort
or die "Can't start sort: $!";
#... # imprime des trucs sur la sortie
close OUTPUT # attend la fin de sort
or warn $! ? "Error closing sort pipe: $!"
: "Exit status $? from sort";
open(INPUT, 'foo') # recupere les resultats de sort
or die "Can't open 'foo' for input: $!";
Le DESCRIPTEUR peut être une expression dont la valeur peut être utilisée en tant que descripteur indirect, habituellement le véritable nom du descripteur.
opendir() et retourne le résultat de
cet appel système.
Le REPDESCRIPTEUR peut être une expression dont la valeur peut être utilisée comme un descripteur indirect de répertoire, habituellement le véritable nom du descripteur de répertoire.
pack()) du type approprié correspondant à la
socket. Voir les exemples de « Sockets : communication Client/Serveur » dans la page de manuel perlipc.
continue rattaché à un BLOC (typiquement dans un
while ou un foreach), il est toujours exécuté juste avant le test à
évaluer à nouveau, tout comme la troisième partie d'une boucle for en C. Il
peut donc être utilisé pour incrémenter une variable de boucle, même si la
boucle a été continuée par l'instruction next (qui est similaire à
l'instruction continue en C).
last, next, ou redo peuvent apparaître dans un bloc
continue. last et redo vont se comporter comme s'ils avaient été
exécutés dans le bloc principal. De même pour next, mais comme il va
exécuter un bloc continue, il peut s'avérer encore plus divertissant.
while (EXPR) {
### redo vient toujours ici
do_something;
} continue {
### next vient toujours ici
do_something_else;
# puis retour au sommet pour revérifier EXPR
}
### last vient toujours ici
Omettre la section continue est sémantiquement équivalent à en
utiliser une vide, de manière assez logique. Dans ce cas, next retourne
directement vérifier la condition au sommet de la boucle.
$_.
Pour la fonction réciproque, vous pouvez utiliser la fonction
Math:;Trig::acos() ou alors utiliser cette relation :
sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }
crypt(3) de la
bibliothèque C (en supposant que vous en avez une version dont elle n'a pas
été extirpée en tant que munition potentielle). Ceci peut s'avérer utile,
entre autres choses, pour vérifier le fichier de mots de passe à la recherche
de mots de passe bancals. Seuls les types portant un chapeau blanc devraient
faire ça.
Notez que crypt() est conçu pour être une fonction à sens unique, un peu
comme les oeufs qu'on casse pour faire une omelette. Il n'y a aucune fonction
(connue) pour décrypter (donc crypt() est une fonction de hachage à sens
unique). Par conséquent, cette fonction n'est pas du tout utile pour de la
cryptographie. (Pour ça, voyez plutôt votre miroir CPAN le plus proche.)
Pour vérifier une chaîne cryptée, vous devriez utiliser cette chaîne cryptée
comme SEL (comme dans crypt($plain, $crypted) eq $crypted). Cela permet à
votre script de fonctionner aussi bien avec le crypt standard qu'avec des
implémentations plus exotiques. En d'autres termes, vous ne pouvez rien
supposer sur le contenu de la chaîne produite ou sur la taille de la chaîne
ainsi chiffrée.
Traditionnellement, le résultat est une chaîne de 13 octets : les deux
premiers octets du SEL, suivis de 11 octets pris dans l'ensemble
[./0-9A-Za-z] et seul les huit premiers octets de la chaîne à encrypter
comptent. Mais des méthodes de hachages alternatives (comme MD5) ou un niveau
de sécurité plus haut (comme C2) ou des implémentations sur des plateformes
non-UNIX peuvent produire d'autres types de chaînes.
Lorsque vous choisissez un nouveau SEL constitué de deux caractères
aléatoires, ces caractères doivent provenir de l'ensemble [./0-9A-Za-z]
(Exemple join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]).
Voici un exemple qui garantit que quiconque lance ce programme connaît son propre mot de passe :
$pwd = (getpwuid($<))[1];
$salt = substr($pwd, 0, 2);
system "stty -echo";
print "Password: ";
chop($word = <STDIN>);
print "\n";
system "stty echo";
if (crypt($word, $salt) ne $pwd) {
die "Sorry...\n";
} else {
print "ok\n";
}
Bien évidemment, donner votre mot de passe à quiconque vous le demande est très peu recommandé.
La fonction crypt n'est pas utilisable pour chiffrer de grande quantité
d'information déjà parce que vous ne pouvez pas retrouver l'information
initiale. Regardez les répertoires by-module/Crypt et by-module/PGP sur
votre miroir CPAN préféré pour y trouver des modules plus pratiques.
Si vous utilisez crypt() sur une chaîne Unicode (qui contient
éventuellement des caractères dont l'encodage est supérieur à 255), Perl
essaie de se sortir de cette situation en dégradant une copie de la chaîne
vers un encodage sur 8 bits avant d'appeler crypt() sur cette copie. Si cela
fonctionne, tout est bon. Sinon, crypt() meurt (die) avec les message Wide
character in crypt.
untie().]
Rompt le lien entre un fichier DBM et une table de hachage.
tie().]
Cette fonction lie un fichier dbm(3), ndbm(3), sdbm(3), gdbm(3), ou Berkeley
DB à une table de hachage. HASH est le nom de la table de hachage. (À la
différence du open() normal, le premier argument n'est pas un
descripteur de fichier, même s'il en a l'air). DBNOM est le nom de la base de
données (sans l'extension .dir ou .pag, le cas échéant). Si la base de
données n'existe pas, elle est créée avec les droits spécifiés par MODE (et
modifiés par umask). Si votre système supporte uniquement les anciennes
fonctions DBM, vous ne pouvez exécuter qu'un seul dbmopen() dans votre
programme. Dans les anciennes versions de Perl, si votre système n'avait ni
DBM ni ndbm, l'appel à dbmopen() produisait une erreur fatale ; il
utilise maintenant sdbm(3).
Si vous n'avez pas les droits d'écriture sur le fichier DBM, vous pouvez
seulement lire les variables de la table de hachage, vous ne pouvez pas y
écrire. Si vous souhaitez tester si vous pouvez y écrire, faites un test sur
le fichier ou essayez d'écrire une entrée bidon dans la table de hachage, à
l'intérieur d'un eval(), qui interceptera l'erreur.
Notez que les fonctions telles que keys() et values() peuvent retourner
des listes gigantesques si elles sont utilisées sur de gros fichiers DBM. Vous
devriez préférer la fonction each() pour parcourir des fichiers DBM
volumineux. Exemple :
# imprime en sortie les index du fichier d'historiques
dbmopen(%HIST,'/usr/lib/news/history',0666);
while (($key,$val) = each %HIST) {
print $key, ' = ', unpack('L',$val), "\n";
}
dbmclose(%HIST);
Voir aussi AnyDBM_File pour une description plus générale des avantages et inconvénients des différentes approches dbm ainsi que DB_File pour une implémentation particulièrement riche.
Vous pouvez contrôler la bibliothèque DBM utilisé en chargeant cette bibliothèque avant l'appel à dbmopen() :
use DB_File;
dbmopen(%NS_Hist, "$ENV{HOME}/.netscape/history.db")
or die "Can't open netscape history file: $!";
undef. Si EXPR est absent, $_ sera vérifiée
de la sorte.
De nombreuses opérations retournent undef pour signaler un échec, la fin
d'un fichier, une erreur système, une variable non initialisée et d'autres
conditions exceptionnelles. Cette fonction vous permet de distinguer undef
des autres valeurs. (Un simple test booléen ne distinguera pas undef, zéro,
la chaîne de caractères vide et <``0''>, qui représentent tous faux.) Notez que
puisque undef est un scalaire valide, sa présence n'indique pas
nécessairement une condition exceptionnelle : pop() retourne undef
quand son argument est un tableau vide ou quand l'élément à retourner a la
valeur undef.
Vous pouvez aussi utiliser defined(&func) pour vérifier si la subroutine
&func a déjà été définie. La valeur retournée ne sera pas affectée par une
déclaration préalable de &func.
L'utilisation de defined() sur des agrégats (tables de hachage et
tableaux) est dépréciée. C'était utilisé pour savoir si de la mémoire avait
déjà été allouée pour cet agrégat. Ce comportement pourrait disparaître
dans une future version de Perl. Vous devriez utiliser un simple test de
taille à la place :
if (@an_array) { print "has array elements\n" }
if (%a_hash) { print "has hash members\n" }
Utilisé sur un élément de table de hachage, il vous indique si la valeur est définie, mais pas si la clé existe dans la table. Utilisez « exists » dans ce but.
Exemples :
print if defined $switch{'D'};
print "$val\n" while defined($val = pop(@ary));
die "Can't readlink $sym: $!"
unless defined($value = readlink $sym);
sub foo { defined &$bar ? &$bar(@_) : die "No bar"; }
$debugging = 0 unless defined $debugging;
Note : de nombreuses personnes ont tendance à trop utiliser defined() et
sont donc surprises de découvrir que le nombre 0 et "" (la chaîne de
caractères vide) sont, en fait, des valeurs définies. Par exemple, si vous
écrivez :
"ab" =~ /a(.*)b/;
La recherche de motif réussit et $1 est définie, malgré le fait
qu'il ne correspond à ``rien''. Mais elle n'a pas véritablement rien
trouvé -- elle a plutôt trouvé quelque chose qui s'est avéré être
d'une longueur de 0 caractères. Tout ceci reste très loyal et
honnête. Quand une fonction retourne une valeur indéfinie, il est
admis qu'elle ne pourrait pas vous donner une réponse honnête. Vous
devriez donc utiliser defined() uniquement lorsque vous vous posez
des questions sur l'intégrité de ce que vous tentez de faire. Sinon,
une simple comparaison avec 0 ou "" est ce que vous voulez.
Voir aussi « undef », « exists », « ref ».
le(s)
élément(s) spécifié(s) de la table de hachage ou du tableau. Dans le cas d'un
tableau, si les éléments supprimés se trouvent à la fin du tableau, la taille
du tableau est réduite à l'indice le plus grand de tous les indices des
éléments restants qui donnent une valeur vraie lorsqu'on teste leur existence
via exists() (ou 0 si aucun élément n'existe).
Retourne tous les éléments ainsi supprimés ou la valeur indéfinie (undef) si
aucun élément n'a été supprimé. Supprimer des éléments dans $ENV{} modifie
les variables d'environnement. Supprimer des éléments d'une table de hachage
liée à un fichier DBM supprime ces éléments du fichier. Supprimer des éléments
d'une table de hachage ou d'un tableau lié ne retourne pas nécessairement
quelque chose.
Supprimer un élément d'un tableau réinitialise effectivement cet emplacement à
sa valeur indéfinie initiale. En conséquence, un test d'existence sur cet
élément via exists() retournera faux. Notez bien que supprimer des éléments au
milieu d'un tableau ne décale pas vers le bas les indices des éléments
suivants -- utiliser splice() pour cela. Voir « exists ».
Le code suivant supprime (de manière inefficace) toutes les valeurs de %HASH et de @TABLEAU :
foreach $key (keys %HASH) {
delete $HASH{$key};
}
foreach $index (0 .. $#TABLEAU) {
delete $TABLEAU[$index];
}
De même que le code suivant :
delete @HASH{keys %HASH}
delete @TABLEAU[0 .. $#TABLEAU];
Ces deux méthodes restent toutefois beaucoup plus lentes que la simple
assignation de la liste vide ou l'utilisation de undef() sur %HASH ou
@TABLEAU :
%HASH = (); # vider complètement %HASH
undef %HASH; # oublier que %HASH a existé
@TABLEAU = (); # vider complètement @TABLEAU
undef @TABLEAU; # oublier que @TABLEAU a existé
Notez que EXPR peut être arbitrairement compliquée tant que l'opération finale se réfère à un élément ou une partie d'une table de hachage ou d'un tableau :
delete $ref->[$x][$y]{$key};
delete @{$ref->[$x][$y]}{$key1, $key2, @morekeys};
delete $ref->[$x][$y][$index];
delete @{$ref->[$x][$y]}[$index1, $index2, @moreindices];
eval(), affiche les valeur de la LISTE sur STDERR et
quitte avec la valeur actuelle de $! (numéro d'erreur errno). Si $! est
0, sort avec la valeur ($? >> 8) (statut d'une `commande` entre
simples apostrophes inverses). Si ($? >> 8) est 0, sort avec
255. À l'intérieur d'un eval(), le message d'erreur est mis dans $@
et le eval() s'achève sur la valeur indéfinie. Ce qui fait de die() la
façon de soulever une exception.
Exemples équivalents :
die "Can't cd to spool: $!\n" unless chdir '/usr/spool/news';
chdir '/usr/spool/news' or die "Can't cd to spool: $!\n"
Si la dernière valeur de LISTE ne se termine pas par un saut de ligne, le
numéro de la ligne actuelle du script et le numéro de la ligne d'entrée (le
cas échéant) sont aussi affichés et un saut de ligne est ajouté. Notez que ``le
numéro de la ligne d'entrée'' (mieux connu sous le nom de ``chunk'') est
dépendant de la notion de ``ligne'' courante et est disponible dans la variable
spéciale $.. Voir « $/ » dans la page de manuel perlvar et « $. » dans la page de manuel perlvar.
Astuce : parfois, la concaténation de ", stopped" à votre message le
rendra plus sensé lorsque la chaîne de caractères "at foo line 123" sera
ajoutée. Supposez que vous exécutiez le script ``canasta''.
die "/etc/games is no good";
die "/etc/games is no good, stopped";
va respectivement produire
/etc/games is no good at canasta line 123.
/etc/games is no good, stopped at canasta line 123.
Voir aussi exit() et warn() et le module Carp.
Si la LISTE est vide et que $@ contient déjà une valeur (typiquement
provenant d'une évaluation précédente), cette valeur est réutilisée après la
concaténation de "\t...propagated". Ceci est utile pour propager des
exceptions :
eval { ... };
die unless $@ =~ /Expected exception/;
Si LISTE est vide et que $@ contient une référence vers un objet qui a une
méthode PROPAGATE, cette méthode sera appelée avec comme argument le nom du
fichier et le numéro de ligne. La valeur retournée remplacera la valeur dans
$@ (comme si <$@ = eval { $@-PROPAGATE(__FILE__, __LINE__) };>> était
appelé).
Si $@ est vide, alors la chaîne de caractères "Died" est utilisée.
L'argument de die() peut aussi être une référence. Lorsque cela arrive à
l'intérieur d'un eval() alors $@ contiendra cette référence. Ce comportement
autorise une implémentation plus élaborée de la gestion des exceptions
utilisant des objets contenant une description arbitraire de la nature de
l'exception. Une telle utilisation est parfois préférable à la reconnaissance
d'un motif particulier par une expression rationnelle appliquée la valeur de
$@. Voici un exemple :
eval { ... ; die Some::Module::Exception->new( FOO => "bar" ) };
if ($@) {
if (ref($@) && UNIVERSAL::isa($@,"Some::Module::Exception")) {
# gestion de Some::Module::Exception
}
else {
# gestion de toutes les autres exceptions
}
}
Étant donné que perl transformera en chaîne toutes les exceptions non captées avant de les afficher, vous voudrez peut-être surcharger l'opération de transformation en chaîne de tous vos objets représentant des exceptions. Regardez overload pour faire cela.
Vous pouvez vous arranger pour qu'une subroutine (de callback) soit appelée
juste après le die() en l'attachant à $SIG{__DIE__}. La subroutine
associée sera appelée avec le texte de l'erreur et peut changer le message de
l'erreur, le cas échéant, en appelant die() à nouveau. Voir
« $SIG{expr} » dans la page de manuel perlvar pour les détails sur l'assignation des entrées de
%SIG et « eval BLOC » pour des exemples. Bien que cette fonctionnalité
ait été conçue afin d'être utilisée juste au moment où votre script se
termine, ce n'est pas le cas -- la subroutine attachée à $SIG{__DIE__} peut
aussi être appelée lors de l'eval()uation d'un bloc ou d'une chaîne ! Si
vous voulez que votre subroutine ne fasse rien dans ce cas, utilisez :
die @_ if $^S;
comme première ligne de votre subroutine (Voir « $^S » dans la page de manuel perlvar). Étant donné que cela peut engendrer des choses étranges, ce comportement contre-intuitif devrait être changé dans une prochaine version.
do BLOC n'est pas considéré comme une boucle et donc les instructions de
contrôle de boucle next, last et redo ne peuvent pas être utilisées
pour quitter ou redémarrer le bloc. Voir la page de manuel perlsyn pour des stratégies
alternatives.
ROUTINE(LISTE)
do 'stat.pl';
est identique à
eval `cat stat.pl`;
sauf que c'est plus efficace et concis, qu'une trace du fichier courant est
gardée pour les messages d'erreur, que la recherche du fichier a lieu dans
dans tous les répertoires de @INC et que, si le fichier est trouvé, %INC
est mis à jour. Voir « Noms prédéfinis » dans la page de manuel perlvar pour ces variables. De plus,
les variables lexicales visibles lors de l'appel ne sont pas vues par do
NOMFICHIER alors qu'elle le sont par eval CHAINE. En revanche, dans les
deux cas, le fichier est retraité à chaque fois que vous l'appeler ce qui
n'est probablement pas ce que vous voudriez faire à l'intérieur d'une boucle.
Si do ne peut pas lire le fichier, il retourne undef et assigne l'erreur à
$!. Si do peut lire le fichier mais non le compiler, il retourne undef
et assigne une message d'erreur à $@. Si le fichier est compilé avec
succès, do retourne la valeur de la dernière expression évaluée.
Notez que l'inclusion de modules de bibliothèques est mieux faite par les
opérateurs use() et require() qui effectuent aussi une vérification
automatique des erreurs et soulèvent une exception s'il y a le moindre
problème.
Vous pourriez aimer utiliser do pour lire le fichier de configuration d'un
programme. La vérification manuelle d'erreurs peut être effectuée de la façon
suivante :
# lecture des fichiers : d'abord le système puis l'utilisateur
for $file ("/share/prog/defaults.rc",
"$ENV{HOME}/.someprogrc") {
unless ($return = do $file) {
warn "couldn't parse $file: $@" if $@;
warn "couldn't do $file: $!" unless defined $return;
warn "couldn't run $file" unless $return;
}
}
goto LABEL
(avec toutes les restrictions dont souffre goto). Pensez-y comme un
branchement goto avec l'intervention d'une image mémoire et une
réincarnation. Si LABEL est omis, relance le programme au
début.
ATTENTION : tout fichier ouvert au moment de la copie ne sera PAS ouvert à nouveau quand le programme sera réincarné, avec pour résultat une confusion possible sur la portion de Perl.
Cet opérateur est très largement obsolète, en partie parce qu'il est très
difficile de convertir un fichier d'image mémoire (core) en exécutable mais
aussi parce que le véritable compilateur perl-en-C l'a surpassé. C'est
pourquoi vous devez maintenant l'appeler par CORE::dump() si vous ne voulez
pas recevoir un message d'avertissement au sujet d'une erreur de frappe
possible.
Si vous projetez d'utiliser dump pour augmenter la vitesse de votre
programme, essayez donc de produire du pseudo-code (ou bytecode) ou du C natif
comme cela est décrit dans perlcc. Si vous essayez juste d'accélérer un
script CGI, regardez donc du côté de l'extension mod_perl de Apache ou
de celui du module CGI::Fast sur CPAN. Vous pouvez aussi envisager
l'autochargement (autoloading ou selfloading) qui donnera au moins la
sensation que votre programme va plus vite.
Les entrées sont apparemment retournées dans un ordre aléatoire. Cet ordre
aléatoire réel pourrait changer dans les versions futures de perl mais vous
avez la garantie que cet ordre sera le même, que vous utilisiez la fonction
keys ou la fonction values sur une même table de hachage (non modifiée).
Quand la table de hachage est entièrement lue, un tableau nul est retourné
dans un contexte de liste (qui, lorsqu'il est assigné, produit une valeur
FAUSSE 0), et undef dans un contexte scalaire. Le prochain appel à
each après cela redémarrera une nouvelle itération. Il y a un seul
itérateur pour chaque table de hachage, partagé par tous les appels à each,
keys ou values du programme ; il peut être réinitialisé en lisant
tous les éléments de la table ou en évaluant keys HASH ou values HASH.
Si vous ajoutez ou supprimez des éléments d'une table de hachage pendant que
vous itérez sur celle-ci, vous pourriez avoir des entrées ignorées ou
dupliquées, donc ne le faites pas.
Le code suivant affiche votre environnement comme le fait le programme printenv(1), mais dans un ordre différent :
while (($key,$value) = each %ENV) {
print "$key=$value\n";
}
ungetc(), elle n'est donc
pas vraiment utile dans un contexte interactif.) Ne faites pas de
lecture sur un fichier d'un terminal (ou d'appel à eof(DESCRIPTEUR)
sur celui-ci) après qu'une fin de fichier soit atteinte. Les types de
fichiers comme les terminaux peuvent perdre la condition de fin de
fichier si vous le faites.
Un eof sans un argument utilise le dernier fichier lu comme
argument. Utiliser eof() avec des parenthèses vides est très différent. Il
se réfère alors au pseudo fichier formé par les fichiers listés sur la ligne
de commande et lu par l'opérateur <>. Puisque <> n'est pas
explicitement ouvert comme l'est un descripteur de fichier normal,
l'utilisation de eof() avant celle de <> déclenchera l'examen de
@ARGV pour voir si une entrée est disponible. De manière similaire, un
eof() après que <> a retourné la condition fin-de-fichier supposera
que vous traitez un autre fichier de la liste @ARGV ou que vous lisez
depuis STDIN. Voir « Les opérateurs d'E/S » dans la page de manuel perlop.
Dans une boucle while (<>) eof(ARGV) ou eof peuvent être
utilisés pour tester la fin de CHAQUE fichier alors que eof() ne
détectera que la fin du tout dernier fichier. Exemple :
# réinitialise le numérotage des lignes sur chaque fichier d'entrée
while (<>) {
next if /^\s*#/; # saute les commentaires
print "$.\t$_";
} continue {
close ARGV if eof; # ce n'est pas eof() !
}
# insère des tirets juste avant la dernière ligne du dernier fichier
while (<>) {
if (eof()) { # vérifie la fin du fichier courant
print "--------------\n";
close(ARGV); # ferme ou s'arrête ; nécessaire en cas
# de lecture sur le terminal
}
print;
}
Astuce pratique : vous n'avez presque jamais besoin d'utiliser eof en
Perl parce que les opérateurs d'entrée retournent la valeur undef quand ils
n'ont plus d'informations à lire ou s'il y a eu une erreur.
$_. Cette forme est typiquement utilisée pour repousser la compilation et
l'exécution du texte contenu dans EXPR jusqu'à l'exécution du programme.
Dans sa seconde forme, le code à l'intérieur du BLOC est parcouru une seule fois -- au même moment que la compilation du code entourant l'évaluation -- et exécuté dans le contexte du programme Perl courant. Cette forme est typiquement utilisée pour intercepter des exceptions plus efficacement que la première (voir ci-dessous), en fournissant aussi le bénéfice d'une vérification du code dans le BLOC lors de la compilation.
Le point-virgule final, le cas échéant, peut être omis dans EXPR ou à l'intérieur du BLOC.
Dans les deux formes, la valeur retournée est la valeur de la dernière expression évaluée à l'intérieur du mini-programme ; il est aussi aussi possible d'utiliser un retour explicite (via return), exactement comme pour les routines. L'expression fournissant la valeur de retour est évaluée en contexte vide, scalaire ou de liste, en fonction du contexte de l'évaluation elle-même. Voir « wantarray » pour de plus amples informations sur la façon dont le contexte d'évaluation peut être déterminé.
En cas d'erreur de syntaxe ou d'exécution ou si une instruction die() est
exécutée, une valeur indéfinie (undef) est retournée par eval() et le
message d'erreur est assigné à $@. S'il n'y a pas d'erreur, vous avez la
garantie que la valeur de $@ sera une chaîne de caractères vide. Prenez
garde au fait qu'utiliser eval() ne dispense Perl ni d'afficher des
messages d'alerte (warnings) sur STDERR ni d'assigner ses messages d'alerte
dans $@. Pour ce faire, il vous faut utiliser les capacités de
$SIG{__WARN__} ou désactiver les messages d'avertissement dans le BLOC ou
l'EXPR en utilisant no warnings 'all'. Voir « warn », la page de manuel perlvar,
warnings et perllexwarn.
Étant donné que eval() intercepte les erreurs non fatales, c'est très
pratique pour déterminer si une fonctionnalité (telle que socket() ou
symlink()) est supportée. C'est aussi le mécanisme d'interception
d'exception de Perl lorsque l'opérateur die est utilisé pour les soulever.
Si le code à exécuter ne varie pas, vous devriez utiliser la seconde forme
avec un BLOC pour intercepter les erreurs d'exécution sans supporter
l'inconvénient de le recompiler à chaque fois. L'erreur, le cas échéant, est
toujours retournée dans $@. Exemples :
# rend une division par zéro non fatale
eval { $answer = $a / $b; }; warn $@ if $@;
# même chose, mais moins efficace
eval '$answer = $a / $b'; warn $@ if $@;
# une erreur de compilation
eval { $answer = }; # MAUVAIS
# une erreur d'exécution
eval '$answer ='; # sets $@
En utilisant la forme eval{} pour une interception d'exception dans des
bibliothèques, vous pourriez souhaiter ne pas exécuter une éventuelle
subroutine attachée à __DIE__ par le code de l'utilisateur. Dans ce cas,
vous pouvez utiliser la construction local $SIG{__DIE__} comme dans
l'exemple ci-dessous :
# une interception d'exception de division par zéro très privée
eval { local $SIG{'__DIE__'}; $answer = $a / $b; };
warn $@ if $@;
Ceci est spécialement significatif, étant donné que les subroutine attachée à
__DIE__ peuvent appeler die() à nouveau, ce qui a pour effet de changer
leurs messages d'erreur :
# les subroutines attachées à __DIE__
# peuvent modifier les messages d'erreur
{
local $SIG{'__DIE__'} =
sub { (my $x = $_[0]) =~ s/foo/bar/g; die $x };
eval { die "foo lives here" };
print $@ if $@; # affiche "bar lives here"
}
Étant donné que cela favorise une action à distance, ce comportement contre-intuitif pourrait changer dans une version future.
Avec eval(), vous devriez faire particulièrement attention à ce qui est
examiné, et quand :
eval $x; # CAS 1
eval "$x"; # CAS 2
eval '$x'; # CAS 3
eval { $x }; # CAS 4
eval "\$$x++"; # CAS 5
$$x++; # CAS 6
Les cas 1 et 2 ci-dessus se comportent de la même façon : ils exécutent le
code inclus dans la variable $x. (Bien que le cas 2 ait des guillemets qui
font se demander au lecteur ce qui se passe -- réponse : rien.) Les cas 3
et 4 se comportent aussi de la même façon : ils exécutent le code '$x'
qui ne fait rien que retourner la valeur de $x. (Le cas 4 est préférable
pour des raisons purement visuelles mais aussi parce qu'il a l'avantage d'être
compilé lors de la compilation plutôt que lors de l'exécution.) Le cas 5 est
un endroit où vous DEVRIEZ normalement souhaiter utiliser des guillemets,
sauf que dans ce cas particulier, vous pouvez juste utiliser les références
symboliques à la place, comme dans le cas 6.
Un eval BLOC n'est pas considéré comme une boucle. Par conséquent, les
instructions de contrôle de boucles next, last, ou redo ne peuvent
être utilisées pour quitter ou refaire le bloc.
exec() exécute une commande système et ne retourne jamais --
utilisez system() à la place de exec() si vous souhaitez qu'elle
retourne. Elle échoue et retourne FAUX si et seulement si la commande n'existe
pas et est exécutée directement plutôt que par votre interpréteur de
commandes (shell) (cf. ci-dessous).
Comme c'est une erreur courante d'utiliser exec() au lieu de system(),
Perl vous alerte si l'expression suivante n'est pas die(), warn(), ou
exit() (si -w est utilisé -- ce que vous faites toujours, évidemment.)
Si vous voulez vraiment faire suivre le exec() d'une autre expression,
vous pouvez utiliser l'une de ces méthodes pour éviter l'avertissement :
exec ('foo') or print STDERR "couldn't exec foo: $!";
{ exec ('foo') }; print STDERR "couldn't exec foo: $!";
S'il y a plus d'un argument dans la LISTE, ou si la LISTE est un tableau de
plus d'une valeur, appelle execvp(3) avec les arguments de la LISTE. S'il n'y
a qu'un seul argument scalaire ou un tableau à un seul élément et que cet
argument contient des méta-caractères du shell, l'argument entier est passé à
l'interpréteur de commandes shell pour son expansion et son exécution (il
s'agit de /bin/sh -c sur les plates-formes Unix, mais cela varie en
fonction des plates-formes.) S'il n'y a aucun méta-caractères du shell dans
l'argument, il est découpé en mots et passé directement à execvp() qui est
plus efficace. Exemples :
exec '/bin/echo', 'Your arguments are: ', @ARGV;
exec "sort $outfile | uniq";
Si vous ne souhaitez pas vraiment exécuter le premier argument mais plutôt l'utiliser pour dissimuler le nom du programme réellement utilisé, vous pouvez spécifier le vrai programme à exécuter comme un ``objet indirect'' (sans virgule) au début de la LISTE. (Ceci force toujours l'interprétation de la LISTE comme une liste multivaluée, même s'il n'y a qu'un seul scalaire dedans.) Exemple :
$shell = '/bin/csh';
exec $shell '-sh'; # prétend qu'il s'agit d'un login shell
ou, plus directement,
exec {'/bin/csh'} '-sh'; # prétend qu'il s'agit d'un login shell
Quand les arguments sont exécutés par le shell système, les résultats seront dépendants de ses caprices et de ses capacités. Voir « `CHAINE` » dans la page de manuel perlop pour plus de détails.
Utiliser un objet indirect avec exec() ou system() est aussi plus
sûr. Cet usage force l'interprétation des arguments comme une liste
multivaluée, même si elle ne contient qu'un seul élément. De cette façon,
vous ne risquez rien des jokers du shell ou de la séparation des mots par des
espaces.
@args = ( "echo surprise" );
system @args; # sujet à des échappement du shell
# si @args == 1
system { $args[0] } @args; # sûr même avec une liste à un seul élément
La première version, celle sans l'objet indirect, exécute le programme
echo, en lui passant "surprise" comme argument. La seconde
version ne le fait pas -- elle essaie d'exécuter un programme
littéralement appelé ``echo surprise'', ne le trouve pas et assigne à
$? une valeur non nulle indiquant une erreur.
Depuis la version v5.6.0, Perl essaie avant d'effectuer le exec()de vider tous
les tampons des fichiers ouverts en écriture mais ce n'est pas le cas sur
toutes les plates-formes (voir la page de manuel perlport). Pour être plus sûr, vous devriez
positionner la variable $| ($AUTOFLUSH en anglais) ou appeler la méthode
autoflush() des objets IO::Handle pour chacun des descripteurs ouverts
afin d'éviter toute perte de données.
Remarquez que exec() n'exécutera ni vos blocs END ni les méthodes
DESTROY de vos objets.
print "Exists\n" if exists $array{$key};
print "Defined\n" if defined $array{$key};
print "True\n" if $array{$key};
print "Exists\n" if exists $hash{$key};
print "Defined\n" if defined $hash{$key};
print "True\n" if $hash{$key};
print "Exists\n" if exists $array[$index];
print "Defined\n" if defined $array[$index];
print "True\n" if $array[$index];
Un élément d'une table de hachage ou d'un tableau ne peut être VRAI que s'il est défini, et défini que s'il existe, mais la réciproque n'est pas nécessairement vraie.
Si EXPR spécifie le nom d'une subroutine, retourne VRAI si la subroutine spécifiée a déjà été déclarée, même si elle est toujours indéfinie. Utiliser un nom de subroutine pour tester si elle existe (exists) ou si elle est définie (defined) ne compte pas comme une déclaration.
print "Exists\n" if exists &subroutine;
print "Defined\n" if defined &subroutine;
Notez que l'expression EXPR peut être arbitrairement compliquée tant qu'au final, elle désigne une subroutine ou un élément d'une table de hachage ou d'un tableau :
if (exists $ref->{A}->{B}->{$key}) { }
if (exists $hash{A}{B}{$key}) { }
if (exists $ref->{A}->{B}->[$ix]) { }
if (exists $hash{A}{B}[$ix]) { }
if (exists &{$ref->{A}{B}{$key}}) { }
Bien que l'élément le plus profond ne soit pas soudainement créé juste parce
son existence a été testée, les éléments intermédiaires, eux, le seront. Par
conséquent, $ref->{"A"} et $ref->{"A"}->{"B"} seront créés à
cause du test d'existence de l'élément lié à la clé $key ci-dessus. Cela
arrivera à chaque fois que l'opérateur flèche est utilisé, y compris dans le
cas suivant :
undef $ref;
if (exists $ref->{"Some key"}) { }
print $ref; # affiche HASH(0x80d3d5c)
Cette génération spontanée un peu surprenante qui, au premier coup d'oeil (ni même au second d'ailleurs), n'est pas dans le contexte d'une lvalue pourrait être supprimée dans une version future.
Voir « Pseudo-tables de hachage : utiliser un tableau comme table de hachage » dans la page de manuel perlref pour des informations spécifiques concernant l'utilisation de
exists() sur les pseudo-hachages.
L'utilisation d'un appel à une subroutine à la place du nom de cette
subroutine comme argument de exists() est une erreur.
exists ⊂ # OK
exists &sub(); # Erreur
$ans = <STDIN>;
exit 0 if $ans =~ /^[Xx]/;
Voir aussi die(). Si l'expression EXPR est omise, quitte avec le statut
0. Les seules valeurs universellement reconnues pour EXPR sont 0 en cas
de réussite et 1 en cas d'erreur ; toutes les autres valeurs sont sujettes
à des interprétations imprévisibles, en fonction de l'environnement dans
lequel le programme Perl est exécuté. Par exemple, terminer un filtre de
messages entrants de sendmail avec comme valeur 69 (EX_UNAVAILABLE)
provoquera la non livraison du message, mais ce n'est pas vrai partout.
Vous ne devriez pas utiliser exit() pour interrompre une routine s'il
existe une chance pour que quelqu'un souhaite intercepter une erreur qui
arrive. Utilisez die() à la place, qui peut être intercepté par un
eval().
La fonction exit() ne termine pas toujours le process immédiatement. Elle
appelle d'abord toutes les routines END définies, mais ces routines END
ne peuvent pas annuler la terminaison. De la même façon, tout destructeur
d'objet qui doit être appelé le sera avant la sortie. Si cela pose problème,
vous pouvez appelé POSIX:_exit($status) pour éviter le traitement des
destructeurs et des subroutine END. Voir la page de manuel perlmod pour les détails.
exp($_).
use Fcntl;
pour avoir les définitions de constantes correctes. Le traitement de
l'argument et la valeur de retour se fait exactement de la même
manière que ioctl() plus bas.
Par exemple :
use Fcntl;
fcntl($filehandle, F_GETFL, $packed_return_buffer)
or die "can't fcntl F_GETFL: $!";
Vous n'avez pas à vérifier le résultat de fnctl() via defined(). Comme
ioctl(), elle transforme le retour 0 de l'appel système en un ``0 but
true'' en Perl. Cette chaîne est vraie dans un contexte booléen et vaut 0
dans un contexte numérique. Elle est aussi exempte des alertes habituelles de
-w sur les conversions numériques impropres.
Notez que fcntl() produira une erreur fatale si elle est utilisée sur une
machine n'implémentant pas fcntl(2). Voir le module Fcntl ou fcntl(2) pour
connaître les fonctions disponibles sur votre système.
select() et pour les opérations POSIX de
manipulation bas niveau de terminaux tty. Si DESCRIPTEUR est une expression,
la valeur est prise comme un descripteur indirect, généralement son nom.
Vous pouvez utiliser ceci pour déterminer si deux descripteurs se réfèrent au même numéro sous-jacent :
if (fileno(THIS) == fileno(THAT)) {
print "THIS and THAT are dups\n";
}
(Les descripteurs connectés à des objets en mémoire via les nouvelles
fonctionnalités de open peuvent retourner une valeur indéfinie bien qu'ils
soient ouverts.)
flock() est une interface Perl portable de verrouillage de
fichiers, bien qu'il ne verrouille que des fichiers en entier, et non pas des
enregistrements.
La sémantique non évidente mais néanmoins traditionnelle de flock consiste
à attendre indéfiniment jusqu'à la libération du verrou. Ce verrou est
purement consultatif. De tels verrous sont plus faciles d'utilisation mais
offrent moins de garantie. Cela signifie que des fichiers verrouillés via
flock peuvent être modifiés par des programmes n'utilisant pas
flock. Voir la page de manuel perlport ou les pages de manuel de votre système pour la
documentation plus détaillée. Il vaut mieux faire avec ce comportement
traditionnel si vous visez la portabilité. (Sinon, libre à vous d'utiliser les
fonctionnalités (``features'') de votre système d'exploitation. Les contraintes
de portabilité ne doivent pas vous empêcher de faire ce que voulez.)
OPERATION peut être LOCK_SH, LOCK_EX ou LOCK_UN, éventuellement combinée avec
LOCK_NB. Ces constantes ont traditionnellement pour valeurs 1, 2, 8 et 4, mais
vous pouvez utiliser les noms symboliques s'ils sont importés du module Fcntl,
soit individuellement, soit en tant que groupe en utilisant la balise
':flock'. LOCK_SH demande un verrou partagé, LOCK_EX demande un verrou
exclusif et LOCK_UN libère un verrou précédemment demandé. Si LOCK_NB est
ajouté à LOCK_SH ou LOCK_EX (via un 'ou' bit à bit) alors flock()
retournera immédiatement plutôt que d'attendre la libération du verrou
(vérifiez le code de retour pour savoir si vous l'avez obtenu).
Pour éviter une mauvaise synchronisation, Perl vide le tampon du DESCRIPTEUR avant de le (dé)verrouiller.
Notez que l'émulation construite avec lockf(3) ne fournit pas de verrous
partagés et qu'il exige que DESCRIPTEUR soit ouvert en écriture. Ce sont les
sémantiques qu'implémente lockf(3). La plupart des systèmes (si ce n'est tous)
implémentent toutefois lockf(3) en termes de verrous fcntl(2), la différence
de sémantiques ne devrait dont pas gêner trop de monde.
Notez que l'émulation de flock(3) via fcntl(2) implique que DESCRIPTEUR soit
ouvert en lecture pour l'utilisation de LOCK_SH et en écriture pour
l'utilisation de LOCK_EX.
Notez aussi que certaines versions de flock() ne peuvent pas verrouiller
des choses à travers le réseau, vous devriez utilisez des appels à fcntl()
plus spécifiques au système dans ce but. Si vous le souhaitez, vous pouvez
contraindre Perl à ignorer la fonction flock(2) de votre système et lui
fournir ainsi sa propre émulation basée sur fcntl(2), en passant le flag
-Ud_flock au programme Configure lors de la configuration de perl.
Voici un empilage de mails pour les systèmes BSD.
use Fcntl ':flock'; # import des constantes LOCK_*
sub lock {
flock(MBOX,LOCK_EX);
# et, si quelqu'un ajoute
# pendant notre attente...
seek(MBOX, 0, 2);
}
sub unlock {
flock(MBOX,LOCK_UN);
}
open(MBOX, ">>/usr/spool/mail/$ENV{'USER'}")
or die "Can't open mailbox: $!";
lock();
print MBOX $msg,"\n\n";
unlock();
Sur les systèmes qui possèdent un vrai flock(), les verrous sont hérités à
travers les appels à fork() alors que ceux qui s'appuient sur la fonction
fcntl() plus capricieuse perdent les verrous, rendant ainsi l'écriture de
serveur plus difficile.
Voir aussi DB_File pour d'autres exemples avec flock().
fork(2) pour créer un nouveau processus exécutant le
même programme au même point. Retourne l'identifiant (pid) de l'enfant au
processus père, 0 au processus fils ou undef en cas d'échec. Les
descripteurs de fichiers (et parfois les verrous posés sur ces descripteurs)
sont partagés sinon tout le reste est recopié. Sur la plupart des systèmes qui
supportent l'appel système fork(), une grande attention a été portée pour
qu'il soit extrêmement efficient (par exemple en utilisant la méthode de
copie-à-l-écriture sur les pages mémoires contenant des données). C'est donc
la paradigme dominant pour la gestion du multi-tâches durant les dernières
décennies.
Depuis la version v5.6.0, Perl tente de vider les tampons de tous les fichiers
ouverts en écriture avant d'effectuer le fork() mais cela n'est pas supporté
sur toutes les plates-formes (voir la page de manuel perlport). Pour être plus sûr, vous
devriez positionner la variable $| ($AUTOFLUSH en anglais) ou appeler la
méthode autoflush() des objets IO::Handle pour chacun des descripteurs
ouverts afin d'éviter toute duplication de données.
Si vous dupliquez avec fork() sans attendre votre fils, vous allez
accumuler des zombis. Sur certains systèmes, vous pouvez éviter cela en
positionnant $SIG{CHLD} à "IGNORE". Voir aussi la page de manuel perlipc pour des
exemples d'utilisation de fork() et de suppression d'enfants moribonds.
Notez que si votre fils dupliqué hérite de descripteurs de fichier systèmes, tels que STDIN et STDOUT, qui sont en fait connectés par un tube ou une socket, même si vous sortez du programme, alors le serveur distant (disons tels que httpd ou rsh) ne saura pas que vous avez terminé. Vous devriez les réouvrir vers /dev/null en cas de problème.
write(). Par
exemple :
format Something =
Test: @<<<<<<<< @||||| @>>>>>
$str, $%, '$' . int($num)
.
$str = "widget";
$num = $cost/$quantity;
$~ = 'Something';
write;
Voir la page de manuel perlform pour de nombreux détails et exemples.
format), bien que
vous puissiez aussi l'appeler. Elle formate (voir la page de manuel perlform) une liste de
valeurs selon le contenu de IMAGE, plaçant la sortie dans l'accumulateur du
format de sortie $^A (ou $ACCUMULATOR en anglais). Finalement, lorsqu'un
write() est effectué, le contenu de $^A est écrit dans un descripteur de
fichier, mais vous pouvez aussi lire $^A vous-même et réassigner "" à
$^A. Notez qu'un format typique appelle formline une fois par ligne du
formulaire mais la fonction formline elle-même ne se préoccupe pas du
nombre de passage à la ligne inclus dans l'IMAGE. Ceci signifie que ~ et
~~ traiteront l'IMAGE complète comme une seule ligne. Vous pouvez donc
utiliser de multiples formline pour implémenter un seul format
d'enregistrement, tout comme le compilateur de format.
Faites attention si vous utilisez des guillemets autour de l'image, car un
caractère ``@'' pourrait être pris pour le début d'un nom de
tableau. formline() retourne toujours VRAI. Cf. la page de manuel perlform pour d'autres
exemples.
if ($BSD_STYLE) {
system "stty cbreak </dev/tty >/dev/tty 2>&1";
}
else {
system "stty", '-icanon', 'eol', "\001";
}
$key = getc(STDIN);
if ($BSD_STYLE) {
system "stty -cbreak </dev/tty >/dev/tty 2>&1";
}
else {
system "stty", 'icanon', 'eol', '^@'; # ASCII null
}
print "\n";
Déterminer la valeur de $BSD_STYLE est laissé en exercice au lecteur.
La fonction POSIX::getattr() peut faire ceci de façon plus portable sur des
systèmes compatibles POSIX. Voir aussi le module Term::ReadKey de votre
site CPAN le plus proche. Les détails sur CPAN peuvent être trouvés dans
« CPAN » dans la page de manuel perlmodlib.
getpwuid().
$login = getlogin || getpwuid($<) || "Kilroy";
N'utilisez pas getlogin() pour de l'authentification : ce n'est pas aussi
sûr que getpwuid().
pack()) de l'autre extrémité de la
connexion SOCKET.
use Socket;
$hersockaddr = getpeername(SOCK);
($port, $iaddr) = unpack_sockaddr_in($hersockaddr);
$herhostname = gethostbyaddr($iaddr, AF_INET);
$herstraddr = inet_ntoa($iaddr);
0 pour obtenir le groupe courant du processus courant. Cela engendra une
exception si on l'utilise sur une machine qui n'implémente pas getpgrp(2). Si
PID est omis, renvoie le groupe du processus courant. Remarquez que la version
POSIX de getpgrp() ne prend pas d'argument PID donc seul PID==0 est
réellement portable.
($name,$passwd,$uid,$gid,
$quota,$comment,$gcos,$dir,$shell,$expire) = getpw*
($name,$passwd,$gid,$members) = getgr*
($name,$aliases,$addrtype,$length,@addrs) = gethost*
($name,$aliases,$addrtype,$net) = getnet*
($name,$aliases,$proto) = getproto*
($name,$aliases,$port,$proto) = getserv*
(Si une entrée n'existe pas, vous récupérerez une liste vide.)
La signification exacte du champ $gcos varie mais contient habituellement le nom réel de l'utilisateur (au contraire du nom de login) et d'autres informations pertinentes pour cet utilisateur. Par contre, sachez que sur de nombreux systèmes, les utilisateurs peuvent changer eux-mêmes ces informations. Ce n'est donc pas une information de confiance. Par conséquent $gcos est souillée (voir la page de manuel perlsec). Les champs $passwd, $shell ainsi que l'interpréteur de commandes (login shell) et le mot de passe crypté sont aussi souillés pour les mêmes raisons.
Dans un contexte scalaire, vous obtenez le nom sauf lorsque la fonction fait une recherche par nom auquel cas vous récupérerez autre chose. (Si une entrée n'existe pas vous récupérerez la valeur undef.) Par exemple :
$uid = getpwnam($name);
$name = getpwuid($num);
$name = getpwent();
$gid = getgrnam($name);
$name = getgrgid($num;
$name = getgrent();
#etc.
Dans getpw*(), les champs $quota, $comment et $expire sont des cas
spéciaux dans le sens où ils ne sont pas supportés sur de nombreux
systèmes. Si $quota n'est pas supporté, c'est un scalaire vide. Si il est
supporté, c'est habituellement le quota disque. Si le champ $comment n'est
pas supporté, c'est un scalaire vide. Si il est supporté, c'est habituellement
le commentaire « administratif » associé à l'utilisateur. Sur certains
systèmes, le champ $quota peut être $change ou $age, des champs qui
sont en rapport avec le vieillissement du mot de passe. Sur certains systèmes,
le champ $comment peut être $class. Le champ $expire, s'il est
présent, exprime la période d'expiration du compte ou du mot de passe. Pour
connaître la disponibilité et le sens exact de tous ces champs sur votre
système, consultez votre documentation de getpwnam(3) et le fichier
pwd.h. À partir de Perl, vous pouvez trouver le sens de vos champs
$quota et $comment et savoir si vous avez le champ $expire en
utilisant le module Config pour lire les valeurs de d_pwquota,
d_pwage, d_pwchange, d_pwcomment et d_pwexpire. Les fichiers de
mots de passe cachés (shadow password) ne sont supportés que si
l'implémentation de votre système est faite telle que les appels aux fonctions
normales de la bibliothèque C accèdent à ces fichiers lorsque vos privilèges
vous y autorisent. Toute autre implémentation incorrecte via des appels à une
bibliothèque séparée n'est pas supportée.
La valeur $members renvoyée par les fonctions getgr*() est la liste des
noms de login des membres du groupe séparés par des espaces.
Pour les fonctions gethost*(), si la variable h_errno est supportée en
C, sa valeur sera retournée via $? si l'appel à la fonction échoue. La
valeur de @addrs qui est retournée en cas de succès est une liste
d'adresses à plat telle que retournée par l'appel système correspondant. Dans
le domaine Internet, chaque adresse fait quatre octets de long et vous pouvez
la décompacter en disant quelque chose comme :
($a,$b,$c,$d) = unpack('C4',$addr[0]);
Si vous êtes fatigué de devoir vous souvenir que tel élément de la liste
retournée correspond à telle valeur, des interfaces par nom sont fournies par
les modules File::stat, Net::hostent, Net::netent, Net::protoent,
Net::servent, Time::gmtime, Time::localtime et User::grent. Ils
remplacent les appels internes normaux par des versions qui renvoient des
objets ayant le nom approprié pour chaque champ. Par exemple :
use File