Content-type: text/html
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.
* - "sub" était un mot-clé dans perl4, mais dans perl5 c'est un opérateur qui peut être utilisé au sein d'expressions.
"-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 perlport et toutes les documentations disponibles spécifiques à la plate-forme considérée.
-r Le fichier est en lecture par le uid/gid effectif. -w Le fichier est en écriture par le uid/gid effectif. -x Le fichier est exécutable par le uid/gid effectif. -o Le fichier appartient au uid effectif.
-R Le fichier est en lecture par le uid/gid réel. -W Le fichier est en écriture par le uid/gid réel. -X Le fichier est exécutable par le uid/gid réel. -O Le fichier appartient au uid réel.
-e Le fichier existe. -z Le fichier a une taille nulle. -s Le fichier n'a pas une taille nulle (retourne sa taille).
-f Le fichier est un fichier normal. -d Le fichier est un répertoire. -l Le fichier est un lien symbolique. -p Le fichier est un tube nommée (FIFO), ou le descripteur est un pipe. -S Le fichier est une socket. -b Le fichier est un fichier blocs spécial. -c Le fichier est un fichier caractères spécial. -t Le fichier est ouvert sur un tty.
-u Le fichier a le bit setuid positionné. -g Le fichier a le bit setgid positionné. -k Le fichier a le sticky bit positionné.
-T Le fichier est un fichier texte ASCII. -B Le fichier est un fichier binaire (le contraire de -T).
-M L'âge du fichier en jours quand le script a été lancé. -A Idem pour le dernier accès au fichier. -C Idem pour le dernier changement de l'inode du fichier.
Exemple :
while (<>) { chop; next unless -f $_; # ignore les fichiers spéciaux #... }
L'interprétation des opérateurs de permission sur le 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.) 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'' in perlvar.
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 CPAN Time::HiRes peut aussi s'avérer utile.
C'est souvent une erreur de mélanger des appels à "alarm()" avec des appels à "sleep()" ("sleep" peut-être implémenté via des appels internes à "alarm" sur votre système.)
Si vous souhaitez utiliser "alarm()" pour contrôler la durée d'un appel système, il vous faut utiliser le couple "eval()"/"die()". Vous ne pouvez pas compter sur l'alarme qui déclenche l'échec de l'appel système avec $! positionné à "EINTR" car Perl met en place des descripteurs de signaux pour redémarrer ces appels sur certains systèmes. Utiliser "eval()"/"die()" fonctionne toujours sous réserve de l'avertissement signalé dans ``Signaux'' in 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]) }
binmode() doit être appelé après open() et avant toute opération d'entrée/sortie sur le descripteur de fichier.
Sur de nombreux systèmes, binmode() n'a aucun effet pour l'instant mais dans le futur il sera étendu pour supporter des disciplines d'entrée et de sortie définies par l'utilisateur. Sur certains systèmes, binmode() est nécessaire lorsque vous travaillez sur des fichiers non textuels. Pour assurer la portabilité, c'est une bonne idée de toujours l'utiliser lorsque c'est approprié et de ne jamais l'utiliser dans les autres cas.
En d'autres termes : indépendamment de la plate-forme, utilisez binmode() sur les fichier binaires et n'utilisez pas binmode() sur les fichiers textes.
Le pragma "open" peut être utilisé pour fixer une discipline par défaut. Voir open.
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 et toutes les variantes d'UNIX 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 n'est pas nécessairement le même sur chaque plate-forme). Par conséquent, binmode() n'a aucun effet sur ces systèmes d'exploitation. Sur d'autres systèmes tels que VMS, MS-DOS et les différentes versions de MS-Windows, votre programme voit un "\n" comme un simple "\cJ" mais ce qui est réellement stocké dans les 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 perlport pour plus d'informations). Voir aussi $/ et "$\" dans perlvar pour savoir comment fixer manuellement les séquences de fin de lignes en entrée et en sortie.
Ne blessez des objets qu'avec des NOMCLASSEs mélangeant des majuscules et des minuscules. Les espaces de nommages entièrement en minuscule sont réservés pour les pragmas Perl. Les types prédé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.
Voir ``Modules Perl'' in perlmod.
($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".) 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 peut avoir optimisé 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()".
$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.
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é.
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)".
$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);
Si NOMBRE est omis, utilise $_.
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.
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.
"last", "next", ou "redo" peuvent apparaître dans un bloc "continue". "last" et "redo" vont se comporter comme si ils avaient été exécutés dans le bloc principal. De même pour "next", mais comme il va exécuter un bloc "continue", il peut s'avérer encore plus divertissant.
while (EXPR) { ### redo vient toujours ici do_something; } continue { ### next vient toujours ici do_something_else; # puis retour au sommet pour revérifier EXPR } ### last vient toujours ici
Omettre la section "continue" est sémantiquement équivalent à en utiliser une vide, de manière assez logique. Dans ce cas, "next" retourne directement vé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] ) }
Notez que "crypt()" est conçu pour être une fonction à sens unique, un peu comme les oeufs qu'on casse pour faire une omelette. Il n'y a aucune fonction (connue) pour décrypter. Par conséquent, cette fonction n'est pas du tout utile pour de la cryptographie. (Pour ça, voyez plutôt votre miroir CPAN le plus proche.)
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. 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.
Rompt le lien entre un fichier DBM et une table de hachage.
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: $!";
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''.
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];
Exemples équivalents :
die "Can't cd to spool: $!\n" unless chdir '/usr/spool/news'; chdir '/usr/spool/news' or die "Can't cd to spool: $!\n"
Si la valeur de EXPR ne se termine pas par un saut de ligne, le numéro de la ligne actuelle du script et le numéro de la ligne d'entrée (le cas échéant) sont aussi 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 ``$/'' in perlvar et ``$.'' in perlvar.
Astuce : parfois, la concaténation de ", stopped" à votre message le rendra plus sensé lorsque la chaîne de caractères "at foo line 123" sera ajoutée. Supposez que vous exécutiez le script ``canasta''.
die "/etc/games is no good"; die "/etc/games is no good, stopped";
va respectivement produire
/etc/games is no good at canasta line 123. /etc/games is no good, stopped at canasta line 123.
Voir aussi "exit()" et "warn()" et le module Carp.
Si la LISTE est vide et que $@ contient déjà une valeur (typiquement provenant d'une évaluation précédente), cette valeur est réutilisée après la concaténation de "\t...propagated". Ceci est utile pour propager des exceptions :
eval { ... }; die unless $@ =~ /Expected exception/;
Si $@ est vide, alors la chaîne de caractères "Died" est utilisée.
L'argument de die() peut aussi être une référence. Lorsque cela arrive à l'intérieur d'un eval() alors $@ contiendra cette référence. Ce comportement autorise une implémentation plus élaborée de la gestion des exceptions utilisant des objets contenant une description arbitraire de la nature de l'exception. Une telle utilisation est parfois préférable à la reconnaissance d'un motif particulier par une expression rationnelle appliquée la valeur de $@. Voici un exemple :
eval { ... ; die Some::Module::Exception->new( FOO => "bar" ) }; if ($@) { if (ref($@) && UNIVERSAL::isa($@,"Some::Module::Exception")) { # gestion de Some::Module::Exception } else { # gestion de toutes les autres exceptions } }
É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}'' in 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'' in 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 perlsyn pour des stratégies alternatives.
do 'stat.pl';
est identique à
scalar 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'' in 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; } }
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é.
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 Fast::CGI 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 cette 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"; }
Voir aussi "keys()" et "values()".
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.
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.
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__}. Voir ``warn'' et perlvar.
Étant donné que "eval()" intercepte les erreurs non fatales, c'est très pratique pour déterminer si une fonctionnalité (telle que "socket()" ou "symlink()") est supportée. C'est aussi le mécanisme d'interception d'exception de Perl lorsque l'opérateur die est utilisé pour les soulever.
Si le code à exécuter ne varie pas, vous devriez utiliser la seconde forme avec un BLOC pour intercepter les erreurs d'exécution sans supporter l'inconvénient de le recompiler à chaque fois. L'erreur, le cas échéant, est toujours retournée dans $@. Exemples :
# rend une division par zéro non fatale eval { $answer = $a / $b; }; warn $@ if $@;
# même chose, mais moins efficace eval '$answer = $a / $b'; warn $@ if $@;
# une erreur de compilation eval { $answer = }; # MAUVAIS
# une erreur d'exécution eval '$answer ='; # sets $@
En utilisant la forme "eval{}" pour une interception d'exception dans des bibliothèques, vous pourriez souhaiter ne pas exécuter une éventuelle subroutine attachée à "__DIE__" par le code de l'utilisateur. Dans ce cas, vous pouvez utiliser la construction "local $SIG{__DIE__}" comme dans l'exemple ci-dessous :
# une interception d'exception de division par zéro très privée eval { local $SIG{'__DIE__'}; $answer = $a / $b; }; warn $@ if $@;
Ceci est spécialement 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.
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`'' in 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 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'' in 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 perlmod pour les détails.
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.
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"; }
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 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 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().
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 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 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.
format Something = Test: @<<<<<<<< @||||| @>>>>> $str, $%, '$' . int($num) .
$str = "widget"; $num = $cost/$quantity; $~ = 'Something'; write;
Voir perlform pour de nombreux détails et exemples.
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. 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'' in perlmod.
$login = getlogin || getpwuid($<) || "Kilroy";
N'utilisez pas "getlogin()" pour de l'authentification : ce n'est pas aussi sûr que "getpwuid()".
use Socket; $hersockaddr = getpeername(SOCK); ($port, $iaddr) = unpack_sockaddr_in($hersockaddr); $herhostname = gethostbyaddr($iaddr, AF_INET); $herstraddr = inet_ntoa($iaddr);
($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 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::stat; use User::pwent; $is_his = (stat($filename)->uid == pwent($whoever)->uid);
Bien que les deux appels se ressemblent (appel à la méthode 'uid'), ce n'est pas la même chose car l'objet "File::stat" est différent de l'objet "User::pwent".
use Socket; $mysockaddr = getsockname(SOCK); ($port, $myaddr) = sockaddr_in($mysockaddr); printf "Connect to %s [%s]\n", scalar gethostbyaddr($myaddr, AF_INET), inet_ntoa($myaddr);
Depuis la version v5.6.0, cet opérateur est implémenté via l'extension standard "File::Glob". Voir File::Glob pour plus de détails.
# 0 1 2 3 4 5 6 7 8 ($sec,$min,$heure,$mjour,$mois,$annee,$sjour,$ajour,$isdst) = gmtime(time);
Tous les éléments du tableau sont numériques et restent tels qu'ils apparaissent dans la structure 'struct tm'. $sec, $min et $heure sont les secondes, les minutes et l'heure de l'instant spécifié. $mjour est le quantième du mois et $mois est le mois lui-même, dans l'intervalle 0..11 avec 0 pour janvier et 11 pour décembre. $annee est le nombre d'années depuis 1900 et donc $annee vaut 123 en l'an 2023. $sjour est le jour de la semaine avec 0 pour le dimanche et 3 pour le mercredi. $ajour est le jour de l'année dans l'intervalle 1..365 (ou 1..366 pour les années bissextiles.) $isdst est vrai si l'heure d'été est en cours à la date spécifiée et faux sinon.
Remarquez bien que $annee n'est pas que les deux derniers chiffres de l'année. Si vous supposez cela, vous créez des programmes non compatible an 2000 --- et vous ne voulez pas faire cela, n'est-ce pas ?
La bonne méthode pour obtenir une année complète sur 4 chiffres est tout simplement :
$annee += 1900;
Et pour obtenir les deux derniers chiffres de l'année (e.g. '01' en 2001):
$annee = sprintf("%02d", $annee % 100);
Si EXPR est omis, calcule "gmtime(time)".
Dans un contexte scalaire, retourne la valeur de ctime(3) :
$now_string = gmtime; # e.g., "Thu Oct 13 04:54:34 1994"
Voir aussi la fonction "timegm()" fournit par le module "Time::Local" et la fonction strftime(3) disponible via le module POSIX.
La valeur scalaire n'est pas dépendante du locale, voir perllocale, mais est construite en interne par Perl. Voir aussi le module "Time::Local" et les fonctions strftime(3) et mktime(3) du module POSIX. Pour obtenir quelque chose de similaire mais dont les chaînes de caractères des dates dépendent du locale, paramétrez vos variables d'environnement liées au locale (voir perllocale) et essayez par exemple :
use POSIX qw(strftime); $now_string = strftime "%a %b %e %H:%M:%S %Y", gmtime;
Notez que les séquences %a et %b qui sont les formes courtes du jour de la semaine et du mois de l'année, n'ont pas obligatoirement 3 caractères de long dans tous les locale.
La forme "goto-EXPR" attend un nom d'étiquette dont la portée sera résolue dynamiquement. Cela autorise les "goto" calculés à la FORTRAN mais ce n'est pas vraiment recommandé si vous vous souciez de la maintenance.
goto ("FOO", "BAR", "GLARCH")[$i];
La forme "goto-&NAME" est vraiment différente des autres formes de "goto". En fait, ce n'est pas du tout un goto et il n'a donc pas les stigmates habituellement associés aux autres goto. Cette forme substitue l'appel de la subroutine en cours d'exécution par un appel à la subroutine donnée en argument. C'est utilisé par les routines "AUTOLOAD" qui désirent charger une autre subroutine puis tout faire comme si c'était cette autre subroutine qui avait réellement été appelée (sauf que toutes les modifications faites à @_ dans la subroutine courante sont propagées à l'autre subroutine). Après le "goto", pas même "caller()" n'est capable de s'apercevoir que la subroutine initiale a été appelée au préalable.
NAME n'est pas nécessairement le nom d'une subroutine ; cela peut être une variable scalaire contenant une référence à du code ou un bloc dont l'évaluation produit une référence à du code.
Elle évalue le bloc BLOC ou l'expression EXPR pour chaque élément de LISTE (qui est localement lié à $_) et retourne la liste des valeurs constituée des éléments pour lesquels l'expression est évaluée à true (vrai). Dans un contexte scalaire, retourne le nombre de fois où l'expression est vraie (true).
@foo = grep(!/^#/, @bar); # supprime les commentaires
ou de manière équivalente :
@foo = grep {!/^#/} @bar; # supprime les commentaires
Remarquez que, puisque $_ est un référence dans la liste de valeurs, il peut être utilisé pour modifier les éléments du tableau. Bien que ce soit supporté et parfois pratique, cela peut aboutir à des résultats bizarres si LISTE n'est pas un tableau nommé. De manière similaire, grep renvoie des alias de la liste originale exactement comme le fait une variable de boucle for. Et donc, modifier un élément d'une liste retournée par grep (par exemple dans un "foreach", un "map()" ou un autre "grep()") modifie réellement l'élément de la liste originale.
Voir aussi ``map'' pour obtenir un tableau composé des résultats de BLOC ou EXPR.
print hex '0xAf'; # affiche '175' print hex 'aF'; # idem
require "ioctl.ph"; # probablement dans /usr/local/lib/perl/ioctl.ph
en premier lieu pour obtenir les définitions correctes des fonctions. Si ioctl.ph n'existe pas ou ne donne pas les définitions correctes, vous devrez les fournir vous-même en vous basant sur les fichiers d'en-tête C tels que <sys/ioctl.h>. (Il existe un script Perl appelé h2ph qui vient avec le kit Perl et qui devrait vous aider à faire cela mais il n'est pas trivial.) SCALAIRE sera lu et/ou modifié selon la fonction FONCTION --- un pointeur sur la valeur alphanumérique de SCALAIRE est passé comme troisième argument du vrai appel système "ioctl()". (Si SCALAIRE n'a pas de valeur alphanumérique mais a une valeur numérique, c'est cette valeur qui sera passée plutôt que le pointeur sur la valeur alphanumérique. Pour garantir que c'est bien ce qui se passera, ajouter 0 au scalaire avant de l'utiliser.) Les fonction "pack()" et "unpack()" permettent de manipuler les différentes structures utilisées par "ioctl()".
Les différentes valeurs retournées par "ioctl" (et "fcntl") sont les suivantes :
si l'OS retourne : alors Perl retournera : -1 la valeur indéfinie (undef) 0 la chaîne "0 but true" autre nombre ce nombre
Ainsi Perl retourne vrai en cas de succès et faux en cas d'échec et vous pouvez encore déterminer la véritable valeur retourné par le système d'exploitation :
$retval = ioctl(...) || -1; printf "System returned %d\n", $retval;
La chaîne spéciale "0 but true" est traitée par -w comme une exception qui ne déclenche pas le message d'avertissement concernant les conversions numériques incorrectes.
Voici un exemple qui rend non bloquant au niveau système le descripteur de fichier "REMOTE". En revanche, vous aurez à gérer vous-même le traitement de $|.
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
$flags = fcntl(REMOTE, F_GETFL, 0) or die "Can't get flags for the socket: $!\n";
$flags = fcntl(REMOTE, F_SETFL, $flags | O_NONBLOCK) or die "Can't set flags for the socket: $!\n";
$_ = join(':', $login,$passwd,$uid,$gid,$gcos,$home,$shell);
Au contraire de "split", "join" ne prend pas un motif comme premier argument. À comparer à ``split''.
Voici encore une autre manière d'afficher votre environnement :
@keys = keys %ENV; @values = values %ENV; while (@keys) { print pop(@keys), '=', pop(@values), "\n"; }
et comment trier tout cela par ordre des clés :
foreach $key (sort(keys %ENV)) { print $key, '=', $ENV{$key}, "\n"; }
Pour trier une table de hachage par valeur, vous aurez à utiliser la fonction "sort()". Voici le tri d'une table de hachage par ordre décroissant de ses valeurs :
foreach $key (sort { $hash{$b} <=> $hash{$a} } keys %hash) { printf "%4d %s\n", $hash{$key}, $key; }
En tant que lvalue (valeur modifiable), "keys()" vous permet de d'augmenter le nombre de réceptacles alloués pour la table de hachage concernée. Cela peut améliorer les performances lorsque vous savez à l'avance qu'une table va grossir. (C'est tout à fait similaire à l'augmentation de taille d'un tableau en affectant une grande valeur à $#tableau.) Si vous dites :
keys %hash = 200;
alors %hash aura au moins 200 réceptacles alloués --- 256 en fait, puisque la valeur est arrondie à la puissance de deux immédiatement supérieure. Ces réceptacles seront conservés même si vous faites "%hash = ()". Utilisez "undef %hash" si vous voulez réellement libérer l'espace alloué. En revanche, vous ne pouvez pas utiliser cette méthode pour réduire le nombre de réceptacles alloués (n'ayez aucune inquiétude si vous le faites tout de même par inadvertance : cela n'a aucun effet).
Voir aussi "each", "values" et "sort".
$cnt = kill 1, $child1, $child2; kill 9, @goners;
Si SIGNAL vaut zéro, aucun signal n'est envoyé. C'est un moyen pratique de vérifier qu'un process existe encore et n'a pas changé son UID. Voir perlport pour vérifier la portabilité d'une telle construction.
Au contraire du shell, en Perl, si SIGNAL est négatif, il « kill » le groupe de processus plutôt que les processus. (Sur System V, un numéro de PROCESSUS négatif « kill » aussi les groupes de processus mais ce n'est pas portable.) Cela signifie que vous utiliserez habituellement une valeur positive comme signal. Vous pouvez aussi utilisez un nom de signal entre apostrophes. Voir ``Signaux'' in perlipc pour tous les détails.
LINE: while (<STDIN>) { last LINE if /^$/; # exit when done with header #... }
"last" ne peut pas être utilisé pour sortir d'un bloc qui doit retourner une valeur comme "eval {}", "sub {}" ou "do {}" et ne devrait pas être utilisé pour sortir d'une opération grep() ou map().
Notez qu'un bloc en lui-même est sémantiquement équivalent à une boucle qui ne s'exécuterait qu'une seule fois. Par conséquent, "last" peut être utilisé pour sortir prématurément d'un tel bloc.
Voir aussi ``continue'' pour une illustration du comment marche "last", "next" et "redo".
En l'absence de EXPR, s'applique à $_.
En l'absence de EXPR, s'applique à $_.
"local()" modifie les variables listées pour qu'elles soient locales au bloc/fichier/eval englobant. Si plus d'une valeur est donnée, la liste doit être placée entre parenthèses. Voir ``Valeurs Temporaires via local()'' in perlsub pour plus de détails, en particulier tout ce qui touche aux tables de hachage et aux tableaux liés (par tie()).
# 0 1 2 3 4 5 6 7 8 ($sec,$min,$heure,$mjour,$mois,$annee,$sjour,$ajour,$isdst) = localtime(time);
Tous les éléments du tableau sont numériques et restent tels qu'ils apparaissent dans la structure 'struct tm'. $sec, $min et $heure sont les secondes, les minutes et l'heure de l'instant spécifié. $mjour est le quantième du mois et $mois est le mois lui-même, dans l'intervalle 0..11 avec 0 pour janvier et 11 pour décembre. $annee est le nombre d'années depuis 1900 et donc $annee vaut 123 en l'an 2023. $sjour est le jour de la semaine avec 0 pour le dimanche et 3 pour le mercredi. $ajour est le jour de l'année dans l'intervalle 1..365 (ou 1..366 pour les années bissextiles.) $isdst est vrai si l'heure d'été est en cours à la date spécifiée et faux sinon.
Remarquez bien que $annee n'est pas que les deux derniers chiffres de l'année. Si vous supposez cela, vous créez des programmes non compatible an 2000 --- et vous ne voulez pas faire cela, n'est-ce pas ?
La bonne méthode pour obtenir une année complète sur 4 chiffres est tout simplement :
$annee += 1900;
Et pour obtenir les deux derniers chiffres de l'année (e.g. '01' en 2001):
$annee = sprintf("%02d", $annee % 100);
En l'absence de EXPR, "localtime()" utilise la date courante ("localtime(time)").
Dans un contexte scalaire, retourne la valeur de ctime(3) :
$now_string = localtime; # e.g., "Thu Oct 13 04:54:34 1994"
La valeur scalaire n'est pas dépendante du locale, voir perllocale, mais est construite de manière interne à Perl. Voir aussi le module "Time::Local" et les fonctions strftime(3) et mktime(3) du module POSIX. Pour obtenir quelque chose de similaire mais dont les chaînes de caractères des dates dépendent du locale, paramétrez vos variables d'environnement liées au locale (voir perllocale) et essayez par exemple :
use POSIX qw(strftime); $now_string = strftime "%a %b %e %H:%M:%S %Y", localtime;
Notez que %a et %b, les formes courtes du jour de la semaine et du mois de l'année, n'ont pas obligatoirement 3 caractères de long.
lock I<CHOSE>
Cette fonction place un verrou coopératif sur une variable, une subroutine ou un objet référencé contenu dans CHOSE jusqu'à ce que lock sorte de la portée du programme. C'est une fonction interne uniquement si votre version de Perl a été construite avec le multi-thread activé et si vous avez dit "use Threads". Sinon, c'est la fonction du même nom définie par l'utilisateur qui est appelée. Voir Thread.
sub log10 { my $n = shift; return log($n)/log(10); }
Voir ``exp'' pour l'opération inverse.
En l'absence de EXPR, utilise $_.
@chars = map(chr, @nums);
transcrit une liste de nombres vers les caractères correspondants. Et :
%hash = map { getkey($_) => $_ } @array;
est juste une manière rigolote de dire :
%hash = (); foreach $_ (@array) { $hash{getkey($_)} = $_; }
Remarquez que du fait que $_ est une référence vers la liste de valeurs, il peut être utilisé pour modifier les éléments du tableau. Bien que cela soit pratique et supporté, cela peut produire des résultats bizarres si LISTE n'est pas un tableau nommé. L'utilisation d'une boucle "foreach" est plus claire dans de nombreux cas. Voir aussi ``grep'' pour produire un tableau composé de tous les éléments de la liste originale pour lesquels BLOC ou EXPR est évalué à vrai (true).
En général, il vaut mieux créer des répertoires avec un MASK permissif et laisser l'utilisateur modifier cela via son "umask" que de fournir un MASK trop restrictif ne permettant pas à l'utilisateur d'être plus permissif. L'exception à cette règle concerne les répertoires ou les fichiers doivent être privés (fichiers de messagerie par exemple). "/umask" discute plus en détails du choix de MASK.
use IPC::SysV;
au préalable pour avoir les définitions correctes des constantes. Si CMD est "IPC_STAT" alors ARG doit être une variable qui pourra contenir la structure "msqid_ds" retournée. Renvoie la même chose que "ioctl()" : la valeur undef en cas d'erreur, "0 but true" pour la valeur zéro ou la véritable valeur dans les autres cas. Voir aussi la documentation de "IPC::SysV" et "IPC::Semaphore::Msg".
LINE: while (<STDIN>) { next LINE if /^#/; # ne pas traiter les commentaires #... }
Si il y avait un bloc "continue" dans cet exemple, il serait exécuté même pour les lignes ignorées. Si LABEL est omis, la commande se réfère au bloc englobant le plus intérieur.
"next" ne peut pas être utilisé pour sortir d'un bloc qui doit retourner une valeur comme "eval {}", "sub {}" ou "do {}" et ne devrait pas être utilisé pour sortir d'une opération grep() ou map().
Voir aussi ``continue'' pour voir comment "last", "next" et "redo" fonctionne.
$val = oct($val) if $val =~ /^0/;
Si EXPR est absent, la commande s'applique à $_. Pour réaliser l'opération inverse (produire la représentation octale d'un nombre), utilisez sprintf() ou printf() :
$perms = (stat("filename"))[2] & 07777; $oct_perms = sprintf "%lo", $perms;
La fonction oct() est couramment utilisée pour convertir une chaîne telle que 644 en un mode d'accès pour fichier par exemple. (perl convertit automatiquement les chaînes en nombres si besoin mais en supposant qu'ils sont en base 10.)
Si EXPR est omis, la variable scalaire du même nom que le DESCRIPTEUR contient le nom du fichier. (Remarquez que les variables lexicales --- celles déclarées par "my()" --- ne fonctionnent pas dans ce cas ; donc si vous utilisez "my()", spécifiez EXPR dans votre appel à open.) Voir perlopentut pour une initiation à l'ouverture de fichiers.
Si MODE est '<' ou rien du tout, le fichier est ouvert en lecture. Si MODE est '>', le fichier est tronqué puis ouvert en écriture en étant créé si nécessaire. Si MODE est '>>', le fichier est ouvert en écriture et en mode ajout. Là encore, il sera créé si nécessaire. Vous pouvez ajouter un '+' devant '>' ou '<' pour indiquer que vous voulez à la fois les droits d'écriture et de lecture sur le fichier ; ceci étant '+<' est toujours mieux pour les mises à jour en lecture/écriture --- le mode '+>' écraserait le fichier au préalable. Habituellement, il n'est pas possible d'utiliser le mode lecture/écriture pour des fichiers textes puisqu'ils ont des tailles d'enregistrements variables. Voir l'option -i dans perlrun pour une meilleure approche. Le fichier est créé avec les droits 0666 modifiés par la valeur de "umask".
Ces différents préfixes correspondent aux différents modes d'ouverture de fopen(3) : 'r', 'r+', 'w', 'w+', 'a' et 'a+'.
Dans sa forme à 1 ou 2 arguments, le mode et le nom de fichier peuvent être concaténés (dans cet ordre), éventuellement séparés par des espaces. Il est possible d'omettre le mode si c'est '<'.
Si le nom de fichier commence par '|', le nom de fichier est interprété comme une commande vers laquelle seront dirigées les sorties (via un tube --- en anglais pipe) et si le nom de fichier se termine par '|', le nom de fichier est interprété comme une commande dont la sortie sera récupérée (via un tube --- en anglais pipe). Voir ``Utilisation de open() pour la CIP'' in perlipc pour des exemples à ce sujet. (Vous ne pouvez pas utiliser "open()" pour une commande qui utiliserait un même tube à la fois pour ses entrées et pour ses sorties mais IPC::Open2, IPC::Open3 et ``Communication Bidirectionnelle avec un autre Processus'' in perlipc proposent des solutions de remplacement.)
Ouvrir '-' revient à ouvrir STDIN tandis qu'ouvrir '>-' revient à ouvrir STDOUT.
Open renvoie une valeur non nulle en cas de succès et undef sinon. Si "open()" utilise un tube, la valeur de retour sera le PID du sous-processus.
Si, par malheur, vous utilisez Perl sur un système qui fait une distinction entre les fichiers textes et les fichiers binaires (les systèmes d'exploitation modernes ne font pas de différence) alors vous devriez regarder du côté de ``binmode'' pour connaître les astuces à ce sujet. La différence entre les systèmes nécessitant "binmode()" et les autres réside dans le format de leurs fichiers textes. Des systèmes tels que Unix, MacOS et Plan9 qui délimitent leurs lignes par un seul caractère et qui encode ce caractère en C par "\n" ne nécessitent pas "binmode()". Les autres en ont besoin.
À l'ouverture d'un fichier, c'est généralement une mauvaise idée de continuer l'exécution normale si la requête échoue, ce qui explique pourquoi "open()" est si fréquemment utilisé en association avec "die()". Même si "die()" n'est pas ce que voulez faire (par exemple dans un script CGI où vous voulez récupérer un message d'erreur joliment présenté (il y a des modules qui peuvent vous aider pour cela)), vous devriez toujours vérifier la valeur retournée par l'ouverture du fichier. L'une des rares exceptions est lorsque vous voulez travailler sur un descripteur non ouvert.
Exemples :
$ARTICLE = 100; open ARTICLE or die "Can't find article $ARTICLE: $!\n"; while (<ARTICLE>) {...
open(LOG, '>>/usr/spool/news/twitlog'); # (log is reserved) # si le open échoue, les sorties sont perdues
open(DBASE, '+<', 'dbase.mine') # ouverture pour mise à jour or die "Can't open 'dbase.mine' for update: $!";
open(DBASE, '+<dbase.mine') # idem or die "Can't open 'dbase.mine' for update: $!";
open(ARTICLE, '-|', "caesar <$article") # décryptage de l'article or die "Can't start caesar: $!";
open(ARTICLE, "caesar <$article |") # idem or die "Can't start caesar: $!";
open(EXTRACT, "|sort >/tmp/Tmp$$") # $$ est notre ID de process or die "Can't start sort: $!";
# traitement de la liste des fichiers fournie en argument
foreach $file (@ARGV) { process($file, 'fh00'); }
sub process { my($filename, $input) = @_; $input++; # c'est une incrémentation de chaîne unless (open($input, $filename)) { print STDERR "Can't open $filename: $!\n"; return; }
local $_; while (<$input>) { # remarquez l'utilisation de l'indirection if (/^#include "(.*)"/) { process($1, $input); next; } #... # ce qu'il faut faire... } }
Vous pouvez aussi, dans la tradition du Bourne shell, spécifier une expression EXPR commençant par '>&' auquel cas le reste de la chaîne sera interprété comme le nom d'un descripteur (ou son numéro si c'est une valeur numérique) à dupliquer puis à ouvrir. Vous pouvez utiliser "&" après ">", ">>", "<", "+>", "+>>" et "+<". Le mode que vous spécifiez devrait correspondre à celui du descripteur original. (La duplication d'un descripteur ne prend pas en compte l'éventuel contenu des buffers (tampons) de stdio (les entrées/sorties standard).)
Voici un script qui sauvegarde, redirige et restaure STDOUT et STDERR :
#!/usr/bin/perl open(OLDOUT, ">&STDOUT"); open(OLDERR, ">&STDERR");
open(STDOUT, '>', "foo.out") || die "Can't redirect stdout"; open(STDERR, ">&STDOUT") || die "Can't dup stdout";
select(STDERR); $| = 1; # fonctionnement sans tampon select(STDOUT); $| = 1; # fonctionnement sans tampon
print STDOUT "stdout 1\n"; # cela fonctionne aussi print STDERR "stderr 1\n"; # pour les processus fils
close(STDOUT); close(STDERR);
open(STDOUT, ">&OLDOUT"); open(STDERR, ">&OLDERR");
print STDOUT "stdout 2\n"; print STDERR "stderr 2\n";
Si vous spécifiez '<&=N', où "N" est un nombre, alors Perl fera l'équivalent d'un "fdopen()" en C sur ce descripteur de fichier ; c'est plus avare en descripteur de fichier. Par exemple :
open(DESCRIPTEUR, "<&=$fd")
Remarquez bien que cette fonctionnalité dépend la fonction fdopen() de votre bibliothèque C. Sur la plupart des systèmes UNIX, fdopen() est connu pour échouer lorsque le nombre de descripteurs de fichiers dépasse une certaine limite, typiquement 255. Si vous avez besoin de descripteurs de fichiers plus nombreux, vous devriez examiner la possibilité de recompiler Perl en utilisant la bibliothèque "sfio".
Si vous ouvrez un tube (pipe) sur la commande '-', i.e. soit '|-' soit '-|', alors vous faites un fork implicite et la valeur de retour de open est le PID du processus fils pour le processus père et 0 pour le processus fils. (Utilisez "defined($pid)" pour savoir si le open s'est bien déroulé.) Le descripteur se comporte normalement pour le père mais pour le processus fils, les entrées/sorties sur ce descripteur se font via STDIN/STDOUT. Dans le processus fils, le descripteur n'est pas ouvert --- les échanges se font via les nouveaux STDIN ou STDOUT. Cela s'avère utile lorsque vous voulez avoir un contrôle plus fin sur la commande exécutée par exemple lorsque vous avez un script setuid et que vous ne voulez pas que le shell traite les méta-caractères dans les commandes. Les lignes suivantes sont quasiment équivalentes (trois à trois) :
open(FOO, "|tr '[a-z]' '[A-Z]'"); open(FOO, '|-', "tr '[a-z]' '[A-Z]'"); open(FOO, "|-") || exec 'tr', '[a-z]', '[A-Z]';
open(FOO, "cat -n '$file'|"); open(FOO, '-|', "cat -n '$file'"); open(FOO, "-|") || exec 'cat', '-n', $file;
Voir ``Ouvertures Sûres d'un Tube'' in perlipc pour plus d'exemples à ce sujet.
À partir de la version v5.6.0, Perl tente de vider les tampons de tous les fichiers ouverts en écriture avant toute opération impliquant un fork mais ce n'est pas supporté sur toutes les plates-formes (voir perlport). Pour être plus sûr, vous devriez positionner la variable $| ($AUTOFLUSH en anglais) ou appelé la méthode "autoflush()" des objets "IO::Handle" pour chacun des descripteurs ouverts afin d'éviter toute perte de données.
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'' in perlvar.
La fermeture d'un descripteur utilisant un tube (pipe) amène le processus père à attendre que son fils se termine puis à retourner la valeur de statut dans $?.
Le nom de fichier passé à open dans la forme à 1 ou 2 arguments aura ses éventuels espaces avant et après supprimés et les caractères de redirection normaux seront respectés. Cette fonctionnalité, connue sous le nom de ``ouverture magique'', autorise plein de bonnes choses. Un utilisateur peut spécifier un nom de fichier tel que ``rsh cat file |'' ou alors vous pouvez modifier certains noms de fichiers selon vos besoins :
$filename =~ s/(.*\.gz)\s*$/gzip -dc < $1|/; open(FH, $filename) or die "Can't open $filename: $!";
Utilisez la forme à 3 arguments pour ouvrir un fichier dont le nom contient des caractères quelconques :
open(FOO, '<', $file);
sinon il est nécessaire de protéger les caractères spéciaux et tous les espaces avant et/ou après :
$file =~ s#^(\s)#./$1#; open(FOO, "< $file\0");
(cela peut ne pas fonctionner sur certains systèmes de fichier bizarres). Vous devez choisir consciemment entre la forme magique ou la forme à 3 arguments de open() :
open IN, $ARGV[0];
autorisera l'utilisateur à spécifier un argument de la forme ""rsh cat file |"" mais ne marchera pas avec un nom de fichier contenant des espaces alors que :
open IN, '<', $ARGV[0];
a exactement les limitation inverses.
Si vous voulez un ``vrai'' "open()" à la C (voir open(2) sur votre système) alors vous devriez utiliser la fonction "sysopen()" qui ne fait rien de magique. C'est un autre moyen de protéger vos noms de fichiers de toute interprétation. Par exemple :
use IO::Handle; sysopen(HANDLE, $path, O_RDWR|O_CREAT|O_EXCL) or die "sysopen $path: $!"; $oldfh = select(HANDLE); $| = 1; select($oldfh); print HANDLE "stuff $$\n"); seek(HANDLE, 0, 0); print "File contains: ", <HANDLE>;
En utilisant le constructeur du paquetage "IO::Handle" (ou de l'une de ses sous-classes telles que "IO::File" ou "IO::Socket"), vous pouvez générer des descripteurs anonymes qui ont la même portée que les variables qui gardent une référence sur eux et qui se ferment automatiquement dès qu'ils sont hors de portée :
use IO::File; #... sub read_myfile_munged { my $ALL = shift; my $handle = new IO::File; open($handle, "myfile") or die "myfile: $!"; $first = <$handle> or return (); # Fermeture automatique ici mung $first or die "mung failed"; # Ou ici. return $first, <$handle> if $ALL; # Ou ici. $first; # Ou ici. }
Voir ``seek()'' pour de plus amples informations sur le mélange entre lecture et écriture.
Un déclaration "our" déclare un variable globale qui sera visible dans toute la portée lexicale de cette déclaration, même entre différents packages. Le package d'appartenance de la variable est déterminée lors de la déclaration et non lors de l'utilisation. Cela signifie que vous aurez les comportements suivants :
package Foo; our $bar; # déclare $Foo::bar $bar = 20;
package Bar; print $bar; # affiche 20 (valeur de $Foo:bar)
De multiples déclarations "our" sont autorisées dans la même portée lexicale si elles sont dans des packages différents. Si elles sont dans le même package, Perl produira un avertissement si vous le lui avez demandé.
use warnings; package Foo; our $bar; # déclare $Foo::bar $bar = 20;
package Bar; our $bar = 30; # déclare $Bar::bar print $bar; # affiche 30
our $bar; # émission d'un avertissement
Le TEMPLATE est une séquence de caractères qui donne l'ordre et le type des valeurs, de la manière suivante :
a Une chaîne ASCII, complétée par des caractères NUL. A Une chaîne ASCII, complétée par des blancs. Z Une chaîne (ASCII) terminée par un caractère NUL, complété par des caractères NUL.
b Une chaîne de bits (en ordre croissant dans chaque octet, comme pour vec()). B Une chaîne de bits (en ordre décroissant dans chaque octet). h Une chaîne hexadécimale (chiffres hexadécimaux faibles en premier). H Une chaîne hexadécimale (chiffres hexadécimaux forts en premier).
c La valeur d'un caractère signé. C La valeur d'un caractère non signé. Ne traite que des octets. Voir U pour Unicode.
s La valeur d'un entier court (short) signé S La valeur d'un entier court (short) non signé (Ce 'short' est _exactement_ sur 16 bits ce qui peut être différent de ce qu'un compilateur C local appelle 'short'. Si vous voulez un short natif, utilisez le suffixe '!'.)
i La valeur d'un entier (integer) signé. I La valeur d'un entier (integer) non signé. (Cet 'integer' est _au moins_ sur 32 bits. Sa taille exact dépend de ce que le compilateur C local appelle 'int' et peut même être plus long que le 'long' décrit à l'item suivant.)
l La valeur d'un entier long (long) signé. L La valeur d'un entier long (long) non signé. (Ce 'long' est _exactement_ sur 32 bits ce qui peut être différent de ce qu'un compilateur C local appelle 'long'. Si vous voulez un long natif, utilisez le suffixe '!'.)
n Un entier court non signé (short) dans l'ordre "réseau" (big-endian). N Un entier long non signé (long) dans l'ordre "réseau" (big-endian). v Un entier court non signé (short) dans l'ordre "VAX" (little-endian). V Un entier long non signé (long) dans l'ordre "VAX" (little-endian). (Ces 'shorts' et ces 'longs' font _exactement_ 16 et 32 bits respectivement.)
q Une valeur quad (64-bit) signée. Q Une valeur quad non signée. (Les quads ne sont disponibles que si votre système supporte les entiers 64-bit _et_ que si Perl a été compilé pour les accepter. Provoquera une erreur fatale sinon.)
f Un flottant simple précision au format natif. d Un flottant double précision au format natif.
p Un pointeur vers une chaîne terminée par un caractère NUL. P Un pointeur vers une structure (une chaîne de longueur fixe).
u Une chaîne uuencodée. U Un code d'un caractère Unicode. Encode en UTF-8 en interne. Fonctionne même si 'use utf8' n'est pas actif.
w Un entier BER compressé. Ses octets représentent chacun un entier non signé en base 128. Les chiffres les plus significatifs viennent en premier et il y a le moins de chiffres possibles. Le huitième bit (le bit de poids fort) est toujours à 1 pour chaque octets sauf le dernier.
x Un octet nul. X Retour en arrière d'un octet. @ Remplissage par des octets nuls jusqu'à une position absolue.
Les règles suivantes s'appliquent :
Utilisé avec "Z", "*" déclenchera l'ajout d'un octet nul final (donc la valeur compactée sera d'un octet plus longue que la longueur ("length") de la valeur initiale).
La valeur de répétition pour "u" est interprétée comme le nombre maximale d'octets à encoder par ligne produite avec 0 et 1 remplacé par 45.
Si la valeur à compacter est trop longue, elle est tronquée. Si elle est trop longue et qu'une longueur explicite $count est fournie, "Z" compactera uniquement "$count-1" octets suivi d'un octet nul. Donc, "Z" compacte un caractère nul final en toutes circonstances.
En partant du début de la chaîne d'entrée de pack(), chaque 8-uplet d'octets est converti en un octet de sortie. Avec le format "b", le premier octet du 8-uplet détermine le bit le moins significatif de l'octet alors qu'avec le format "B", il détermine le bit le plus significatif.
Si la longueur de la chaîne d'entrée n'est pas exactement divisible par 8, le reste est compacté comme si la chaîne d'entrée était complétée par des octets nuls à la fin. De manière similaire, lors du décompactage, les bits ``supplémentaires'' sont ignorés.
Si la chaîne d'entrée de pack() est plus longue que nécessaire, les octets en trop sont ignorés. Une valeur de répétition de "*" demande à utiliser tous les octets du champ d'entrée. Lors du décompactage, les bits sont convertis en une chaîne de "0" et de "1".
Chaque octet du champ d'entrée de pack() génère 4 bits du résultat. Pour les octets non alphabétiques, le résultat est basé sur les 4 bits les moins significatifs de l'octet considéré (i.e. sur "ord($octet)%16"). En particulier, les octets "0" et "1" génèrent 0 et 1 comme le font les octets "\0" et "\1". Pour les octets "a".."f" et "A".."F", le résultat est compatible avec les chiffres hexadécimaux habituels et donc "a" et "A" génèrent tous les deux le groupe de 4 bits "0xa==10". Le résultat pour les octets "g".."z" et "G".."Z" n'est pas clairement défini.
En partant du début de la chaîne d'entrée de pack(), chaque paire d'octets est convertie en 1 octet de sortie. Avec le format "h", le premier octet de la paire détermine les 4 bits les moins significatifs de l'octet résultant alors qu'avec le format "H", il détermine les 4 bits les plus significatifs.
Si la longueur de la chaîne d'entrée n'est pas paire, pack() se comportera comme si un octet nul avait été ajouté à la fin. De manière similaire, lors du décompactage (par unpack()), les groupes de 4 bits supplémentaires sont ignorés.
Si la chaîne d'entrée de pack() est plus longue que nécessaire, les octets supplémentaires sont ignorés. Une valeur de répétition de "*" demande à utiliser tous les octets de la chaîne d'entrée. Lors du décompactage, les bits sont convertis en une chaîne de chiffres hexadécimaux.
longueur-item peut être n'importe quel type de lettre d'un TEMPLATE "pack" et décrit la manière dont la longueur est compactée. Les plus courantes sont "n" (pour les chaînes Java), "w" (pour ASN.1 ou SNMP) et "N" (pour les XDR de SUN).
chaine-item doit être, si il est présent, "A*", "a*" ou "Z*". Pour le décompactage (via unpack()), la longueur de la chaîne est celle obtenue par longueur-item mais si vous spécifiez '*', elle sera ignorée.
unpack 'C/a', "\04Gurusamy"; donne 'Guru' unpack 'a3/A* A*', '007 Bond J '; donne (' Bond','J') pack 'n/a* w/a*','hello,','world'; donne "\000\006hello,\005world"
longueur-item n'est pas retourné explicitement par unpack().
L'ajout d'un compteur de répétition à la lettre longueur-item est inutile sauf si cette lettre est "A", "a" ou "Z". Le compactage avec une longueur-item spécifiée par "a" ou "Z" peut introduire des caractères "\000" que Perl ne considérera pas comme légal dans une chaîne numérique.
print length(pack("s")), " ", length(pack("s!")), "\n"; print length(pack("l")), " ", length(pack("l!")), "\n";
"i!" et "I!" fonctionne aussi mais uniquement dans un souci de complétude puisqu'ils sont totalement identique à "i" et "I".
La taille réelle (en octets) des short, int, long et long long natifs sur la plate-forme où Perl a été installé est aussi disponible via Config :
use Config; print $Config{shortsize}, "\n"; print $Config{intsize}, "\n"; print $Config{longsize}, "\n"; print $Config{longlongsize}, "\n";
($Config{longlongsize} sera indéfini (undef) si votre système ne supporte pas les long long).
0x12 0x34 0x56 0x78 # ordre little-endian 0x78 0x56 0x34 0x12 # ordre big-endian
À la base, les CPU des familles Intel, Alpha et VAX sont little-endian alors que tous les autres, par exemple Motorola m68k/88k, PPC, Sparc, HP PA, Power et Cray, sont big-endian. Les MIPS peuvent être les deux : Digital les utilise en mode little-endian ; SGI les utilise en mode big-endian.
Les noms ``big-endian'' et ``little-endian'' sont des références au grand classique ``Les voyages de Gulliver'' (au travers de l'article ``On Holy Wars and a Plea for Peace'' par Danny Cohen, USC/ISI IEN 137, April 1, 1980) et donc aux habitudes des mangeurs d'oeufs Lilliputiens.
Quelques systèmes peuvent même avoir un ordre des octets encore plus bizarre tel que :
0x56 0x78 0x12 0x34 0x34 0x12 0x78 0x56
Vous pouvez voir les préférences de votre systèmes par
print join(" ", map { sprintf "%#02x", $_ } unpack("C*",pack("L",0x12345678))), "\n";
L'ordre des octets de la plate-forme où Perl a été installé est aussi disponible via Config :
use Config; print $Config{byteorder}, "\n";
Les ordres d'octets '1234' et '12345678' sont little-endian alors que '4321' et '87654321' sont big-endian.
Si vous voulez des entiers compactés portables, il vous faut utiliser les formats "n", "N", "v" et "V" puisque leur taille et l'ordre de leurs octets sont connus. Voir aussi perlport.
Sachez que Perl utilise des doubles en interne pour tous les calculs numériques et qu'une conversion de double vers float puis retour vers double amène à une perte de précision (i.e., "unpack("f", pack("f", $foo)") est généralement différent de $foo).
Exemples :
$foo = pack("CCCC",65,66,67,68); # foo eq "ABCD" $foo = pack("C4",65,66,67,68); # même chose $foo = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9); # même chose avec des lettres cerclées Unicode
$foo = pack("ccxxcc",65,66,67,68); # foo eq "AB\0\0CD"
# note : les exemples précédents utilisant "C" et "c" ne sont # corrects que sus des systèmes ACSII ou dérivés comme ISO Latin 1 # ou UTF-8. En EBCDIC, le premier exemple devrait être # $foo = pack("CCCC",193,194,195,196);
$foo = pack("s2",1,2); # "\1\0\2\0" sur little-endian # "\0\1\0\2" sur big-endian
$foo = pack("a4","abcd","x","y","z"); # "abcd"
$foo = pack("aaaa","abcd","x","y","z"); # "axyz"
$foo = pack("a14","abcdefg"); # "abcdefg\0\0\0\0\0\0\0"
$foo = pack("i9pl", gmtime); # une vraie struct tm (sur mon système en tous cas)
$utmp_template = "Z8 Z8 Z16 L"; $utmp = pack($utmp_template, @utmp1); # une struct utmp (BSD-isme)
@utmp2 = unpack($utmp_template, $utmp); # "@utmp1" eq "@utmp2"
sub bintodec { unpack("N", pack("B32", substr("0" x 32 . shift, -32))); }
$foo = pack('sx2l', 12, 34); # short 12, two zero bytes padding, long 34 $bar = pack('s@4l', 12, 34); # short 12, zero fill to position 4, long 34 # $foo eq $bar
La même valeur de TEMPLATE peut généralement être utilisée avec la fonction unpack().
Si NAMESPACE est omis alors il n'y a pas de paquetage courant et tous les identificateurs doivent être soit complètement qualifiés soit lexicaux. C'est plus strict que "use strict" puisque cela inclut aussi les noms de fonctions.
Voir ``Paquetages'' in perlmod pour des plus amples informations à propos des paquetages (packages), des modules et des classes. Voir perlsub pour tous les problèmes de portée.
Voir IPC::Open2, IPC::Open3 et ``Communication Bidirectionnelle avec un autre Processus'' in perlipc pour des exemples sur tout ça.
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'' in perlvar.
$TABLEAU[$#TABLEAU--]
Si le tableau est vide, c'est la valeur undef qui est retournée (cela peut arriver dans d'autres cas aussi). Si TABLEAU est omis, pop dépilera soit le tableau @ARGV dans le programme principale soit @_ dans les subroutines, exactement comme "shift()".
Notez que si vous stockez vos DESCRIPTEUR dans un tableau (ou quelque chose qui nécessite une expression), vous devrez utiliser un bloc qui retourne une valeur :
print { $files[$i] } "stuff\n"; print { $OK ? STDOUT : STDERR } "stuff\n";
Ne tombez pas de le piège d'utiliser "printf()" alors qu'un simple "print()" suffirait. "print()" est plus efficace et moins sujet à erreur.
Si FONCTION est une chaîne commençant par "CORE::", la suite de la chaîne se réfère au nom d'une fonction interne de Perl. Si la fonction interne n'est pas redéfinissable (par exemple "qw//") ou si ses arguments ne peuvent s'exprimer sous forme de prototype (par exemple "system()") - en d'autres termes, si la fonction interne ne se comporte pas comme une fonction Perl - la fonction prototype retournera "undef". Sinon, c'est la chaîne qui décrit le prototype qui est retournée.
for $value (LISTE) { $TABLEAU[++$#TABLEAU] = $value; }
mais en plus efficace. Retourne le nouveau nombre d'éléments du tableau.
Si EXPR est omis, s'appliquera à $_.
(Remarque : si votre fonction rand retourne régulièrement des nombres trop grands ou trop petits alors votre version de Perl a probablement été compilée avec une valeur erronée pour RANDBITS.)
Si vous prévoyez de faire des tests de fichiers sur les valeurs retournées par "readdir()", n'oubliez pas de les préfixer par le répertoire en question. Sinon, puisqu'aucun appel à "chdir()" n'est effectué, vous risquez de tester un mauvais fichier.
opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!"; @dots = grep { /^\./ && -f "$some_dir/$_" } readdir(DIR); closedir DIR;
Lorsque $/ est positionné à "undef", que readline() est utilisé dans un contexte scalaire (i.e. en mode 'slurp') et que le fichier lu est vide, le premier appel retourne '' et "undef" pour les suivants.
C'est la fonction interne qui implémente l'opérateur "<EXPR>" mais vous pouvez l'utiliser directement. L'opérateur "<EXPR>" est décrit en détail dans ``Les opérateurs d'E/S'' in perlop.
$line = <STDIN>; $line = readline(*STDIN); # même chose
# un programme simple pour supprimer les commentaires en Pascal # (Attention: suppose qu'il n'y pas de { ni de } dans les chaînes.) LINE: while (<STDIN>) { while (s|({.*}.*){.*}|$1 |) {} s|{.*}| |; if (s|{.*| |) { $front = $_; while (<STDIN>) { if (/}/) { # end of comment? s|^|$front\{|; redo LINE; } } } print; }
"redo" ne peut pas être utilisé pour redémarrer un bloc qui doit retourner une valeur comme "eval {}", "sub {}" ou "do {}" et ne devrait pas être utilisé pour sortir d'une opération grep() ou map().
Remarques qu'un bloc en lui-même est sémantiquement identique à une boucle qui ne s'exécute qu'une fois. Donc "redo" dans un tel bloc le transforme effectivement en une construction de boucle.
Voir aussi ``continue'' pour illustrer la manière dont "last", "next" et "redo" fonctionnent.
SCALAR ARRAY HASH CODE REF GLOB LVALUE
Si l'objet référencé a été béni (par bless()) par un paquetage alors le nom du paquetage est retourné. Vous pouvez voir "ref()" comme une sorte d'opérateur "typeof()" (type de).
if (ref($r) eq "HASH") { print "r is a reference to a hash.\n"; } unless (ref($r)) { print "r is not a reference at all.\n"; } if (UNIVERSAL::isa($r, "HASH")) { # for subclassing print "r is a reference to something that isa hash.\n"; }
Voir aussi perlref.
Le comportement de cette fonction varie beaucoup d'un système à l'autre. Par exemple, habituellement elle ne fonctionne pas entre des systèmes de fichiers différents même si la commande système mv réussit parfois à le faire. Il y a d'autres restrictions selon que cela fonctionne ou non sur des répertoires, sur des fichiers ouverts ou sur des fichiers préexistants. Regarder perlport et la page de documentation de rename(2) pour les détails.
Si VERSION est spécifiée comme une chaîne de la forme v5.6.1, exige que la version courante de Perl ($^V ou $PERL_VERSION) soit au moins aussi récente que cette VERSION, lors de l'exécution. (Pour des raisons de compatibilité avec les vieilles version de Perl, un argument numérique sera aussi interprété comme une VERSION). Comparez avec ``use'' qui peut faire un contrôle similaire mais lors de la compilation.
require v5.6.1; # contrôle de version à l'exécution require 5.6.1; # idem require 5.005_03; # argument numérique autorisé par compatibilité
Sinon, exige que le fichier d'une bibliothèque soit inclus si ce n'est pas déjà fait. Le fichier est inclus via le mécanisme do-FICHIER qui est pratiquement une variante de "eval()". Sa sémantique est similaire à la procédure suivante :
sub require { my($filename) = @_; return 1 if $INC{$filename}; my($realfilename,$result); ITER: { foreach $prefix (@INC) { $realfilename = "$prefix/$filename"; if (-f $realfilename) { $INC{$filename} = $realfilename; $result = do $realfilename; last ITER; } } die "Can't find $filename in \@INC"; } delete $INC{$filename} if $@ || !$result; die $@ if $@; die "$filename did not return true value" unless $result; return $result; }
Remarquez que le fichier ne sera pas inclus deux fois sous le même nom. Le fichier doit retourner true (vrai) par sa dernière instruction pour indiquer un exécution correcte du code d'initialisation. Il est donc courant de terminer un tel fichier par un ""1;"`` à moins d'être sûr qu'il retournera true (vrai) par un autre moyen. Mais il est plus sûr de mettre ''"1;"" au cas où vous ajouteriez quelques instructions.
Si EXPR est un nom simple (bareword), require suppose l'extension ".pm`` et remplace pour vous les ''::`` par des ''/" dans le nom du fichier afin de rendre plus simple le chargement des modules standards. Cette forme de chargement des modules ne risque pas d'altérer votre espace de noms.
En d'autres termes, si vous dites :
require Foo::Bar; # un splendide mot simple
La fonction require cherchera en fait le fichier "Foo/Bar.pm" dans les répertoires spécifiés par le tableau @INC.
Mais si vous essayez :
$class = 'Foo::Bar'; require $class; # $class n'est pas un mot simple #ou require "Foo::Bar"; # n'est pas un mot simple à cause des guillemets
La fonction require cherchera le fichier "Foo::Bar" dans les répertoires du tableau @INC et se plaindra qu'elle ne peut trouver le fichier "Foo::Bar". Dans ce cas, vous pouvez faire :
eval "require $class";
Pour une fonctionnalité d'importation encore plus puissante, voir ``use'' et perlmod.
reset 'X'; # réinitialise toutes les variables X... reset 'a-z'; # réinitialise toutes les variables # commençant par une minuscule reset; # réinitialise juste les motifs ?...?
Réinitialiser "A-Z" n'est pas recommandé parce que cela efface les tableaux @ARGV et @INC ainsi que la table de hachage %ENV. Ne réinitialise que les variables de paquetage --- les variables lexicales ne sont pas modifiées mais elles s'effacent toutes seules dès que l'on sort de leur portée, ce qui devrait vous inciter à les utiliser. Voir ``my''.
(Remarque : en l'absence de return, une subroutine, un bloc eval ou un do FICHIER retournera automatiquement la valeur de la dernière expression évaluée.)
print reverse <>; # tac (cat à l'envers) les lignes, # la dernière ligne en premier
undef $/; # pour un <> efficace print scalar reverse <>; # tac (cat à l'envers) les octets, # la dernière ligne en reimerp
Cet opérateur est aussi utilisé pour inverser des tables de hachage bien que cela pose quelques problèmes. Si une valeur est dupliquée dans la table originale, seule l'une des ces valeurs sera représentée comme une clé dans la table résultante. Cela nécessite aussi de mettre toute la table à plat avant d'en reconstruire une nouvelle ce qui peut prendre beaucoup de temps sur une grosse table telle qu'un fichier DBM.
%by_name = reverse %by_address; # Inverse la table
@counts = ( scalar @a, scalar @b, scalar @c );
Il n'y pas d'opérateur équivalent pour contraindre l'interprétation d'une expression dans un contexte de liste parce qu'en pratique ce n'est jamais nécessaire. Si vous en avez réellement besoin, vous pouvez utiliser une construction comme "@{[ (une expression) ]}" mais un simple "(une expression)" suffit en général.
Comme "scalar" est un opérateur unaire, si vous l'utilisez accidentellement sur une EXPR constituée d'une liste entre parenthèses, cela se comporte comme l'opérateur scalaire virgule en évaluant tous les éléments dans un contexte vide sauf le dernier élément qui est évalué dans un contexte scalaire et retourné. C'est rarement ce que vous vouliez.
L'instruction suivante :
print uc(scalar(&foo,$bar)),$baz;
est équivalente à ces deux instructions :
&foo; print(uc($bar),$baz);
Voir perlop pour les détails sur les opérateurs unaires et l'opérateur virgule.
Si vous voulez régler la position pour un fichier dans le but d'utiliser "sysread()" ou "syswrite()", n'utilisez pas "seek()" --- la bufferisation rend ses effets imprévisibles et non portables. Utilisez "sysseek()" à la place.
À cause des règles et de la rigueur du C ANSI, sur certains systèmes, vous devez faire un seek à chaque fois que vous basculez entre lecture et écriture. Entre autres choses, cela a pour effet d'appeler la fonction clearerr(3) de stdio. Un WHENCE de 1 ("SEEK_CUR") est pratique pour ne pas modifier la position dans le fichier :
seek(TEST,0,1);
C'est aussi très pratique pour les applications qui veulent simuler "tail -f". Une fois rencontré un EOF en lecture et après avoir attendu un petit peu, vous devez utiliser seek() pour réactiver les choses. L'appel à "seek()" ne modifie pas la position courante mais par contre, il efface la condition fin-de-fichier (EOF) sur le descripteur et donc, au prochain "<FILE>", Perl essayera à nouveau de lire quelque chose. Espérons-le.
Si cela ne marche pas (certaines bibliothèques stdio sont particulièrement hargneuses) alors vous devrez faire quelque chose comme :
for (;;) { for ($curpos = tell(FILE); $_ = <FILE>; $curpos = tell(FILE)) { # search for some stuff and put it into files } sleep($for_a_while); seek(FILE, $curpos, 0); }
select(REPORT1); $^ = 'report1_top'; select(REPORT2); $^ = 'report2_top';
DESCRIPTEUR peut être une expression dont le résultat donne le nom du descripteur réel. Donc :
$oldfh = select(STDERR); $| = 1; select($oldfh);
Certains programmeurs préfèrent considérer les descripteurs comme des objets avec des méthodes. Ils écriraient donc l'exemple précédent de la manière suivante :
use IO::Handle; STDERR->autoflush(1);
$rin = $win = $ein = ''; vec($rin,fileno(STDIN),1) = 1; vec($win,fileno(STDOUT),1) = 1; $ein = $rin | $win;
Si vous voulez surveiller de nombreux descripteurs, vous aurez peut-être à écrire une subroutine :
sub fhbits { my(@fhlist) = split(' ',$_[0]); my($bits); for (@fhlist) { vec($bits,fileno($_),1) = 1; } $bits; } $rin = fhbits('STDIN TTY SOCK');
L'appel classique est :
($nfound,$timeleft) = select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
ou pour attendre que quelque chose soit prêt :
$nfound = select($rout=$rin, $wout=$win, $eout=$ein, undef);
De nombreux systèmes ne prennent pas la peine de retourner quelque chose d'utile dans $timeleft (le temps restant). En conséquence, un appel à select() dans un contexte scalaire retourne juste $nfound.
undef est une valeur acceptable pour les masques de bits. Le timeout, si il est spécifiée, est donné en secondes et peut être fractionnaire. Note : certaines implémentations ne sont pas capables de retourner $timeleft. Dans ce cas, elles retournent toujours un $timeleft égal au $timeout fourni.
Vous pouvez spécifier une attente de 250 millisecondes de la manière suivante :
select(undef, undef, undef, 0.25);
ATTENTION : il ne faut pas mélanger des E/S bufferisées (comme "read()" ou <FH>) avec "select()" excepté lorsque la norme POSIX le permet et, dans ce cas, uniquement sur les systèmes POSIX. Vous devez utiliser "sysread()" à la place.
use IPC::SysV;
au préalable pour avoir les définitions correctes des constantes. Si CMD est IPC_STAT ou GETALL alors ARG doit être une variable capable de contenir la structure semid_ds retournée ou le tableau des valeurs des sémaphores. Les valeurs retournées sont comme celles de "ioctl()" : la valeur undef en cas d'erreur, la chaîne "0 but true" pour rien ou la vraie valeur retournée dans les autres cas. ARG doit être un vecteur d'entiers courts (short) natifs qui peut être créé par "pack("s!",(0)x$nsem)". Voir aussi la documentation de "IPC::SysV" et de "IPC::SysV::Semaphore".
$semop = pack("sss", $semnum, -1, 0); die "Semaphore trouble: $!\n" unless semop($semid, $semop);
Pour envoyer un signal au sémaphore, remplacez le "-1" par 1. Voir aussi la documentation de "IPC::SysV" et de "IPC::SysV::Semaphore".
Voir aussi "unshift", "push" et "pop". "shift()" et "unshift()" agissent sur le côté gauche d'un tableau exactement comme "pop()" et "push()" le font sur le côté droit.
use IPC::SysV;
au préalable pour avoir les définitions correctes des constantes. Si CMD est "IPC_STAT" alors ARG doit être une variable capable de contenir la structure "shmid_ds" retournée. Les valeurs retournées sont comme celles de "ioctl()" : la valeur undef en cas d'erreur, la chaîne "0 but true" pour zéro ou la vraie valeur retournée dans les autres cas. Voir aussi la documentation de "IPC::SysV".
shutdown(SOCKET, 0); # J'ai arrêté de lire des données shutdown(SOCKET, 1); # J'ai arrêté d'écrire des données shutdown(SOCKET, 2); # J'ai arrêté d'utiliser ce socket
C'est pratique pour des sockets pour lesquels vous voulez indiquer à l'autre extrémité que vous avez fini d'écrire mais pas de lire ou vice versa. C'est aussi une forme plus insistante de close puisque qu'elle désactive aussi le descripteur de fichier pour tous les process dupliqués par fork.
Pour calculer la fonction inverse du sinus, vous pouvez utiliser la fonction "Math::Trig::asin" ou utiliser cette relation :
sub asin { atan2($_[0], sqrt(1 - $_[0] * $_[0])) }
Sur quelques vieux systèmes, il se peut que la durée du sommeil soit d'une seconde de moins que celle que vous avez demandée en fonction de la manière dont il compte les secondes. Les systèmes plus modernes s'endorment toujours pendant la bonne durée. En revanche, il peut arriver que votre sommeil dure plus longtemps que prévu sur un système multi-tâches très chargé.
Pour des délais d'une granularité inférieure à la seconde, vous pouvez utiliser l'interface Perl "syscall()" pour accéder à setitimer(2) si votre système le supporte ou sinon regarder ``select()'' plus haut. Le module Time::HiRes disponible sur CPAN peut aussi aider.
Regarder aussi la fonction "sigpause()" du module POSIX.
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'' in perlvar.
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'' in perlvar.
Certains systèmes définissent "pipe()" en terme de "socketpair()", auquel cas un appel à "pipe(Rdr, Wtr)" est quasiment équivalent à :
use Socket; socketpair(Rdr, Wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC); shutdown(Rdr, 1); # plus d'écriture pour le lecteur shutdown(Wtr, 0); # plus de lecture pour l'écrivain
Voir perlipc pour des exemples d'utilisation de socketpair.
Si le prototype de la subroutine est "($$)", les éléments à comparer sont passés par référence dans @_ comme pour une subroutine normale. C'est plus lent qu'une subroutine sans prototype pour laquelle les éléments à comparer sont passés à la subroutine par les variables globales du package courant $a et $b (voir exemples ci-dessous). Dans ce dernier cas, il est contre-productif de déclarer $a et $b comme des variables lexicales.
Dans tous les cas, la subroutine ne peut pas être récursive. Les valeurs à comparer sont toujours passées par référence. Donc, ne les modifiez pas.
Vous ne pouvez pas non plus sortir du bloc sort ou de la subroutine en utilisant un "goto()" ou les opérateurs de contrôle de boucles décrits dans perlsyn.
Lorsque "use locale" est actif, "sort LISTE" trie LISTE selon l'ordre (collation) du locale courant. Voir perllocale.
Exemples :
# tri alphabétique @articles = sort @files;
# idem mais avec une routine de tri explicite @articles = sort {$a cmp $b} @files;
# idem mais indépendant de la casse @articles = sort {uc($a) cmp uc($b)} @files;
# idem mais dans l'ordre inverse @articles = sort {$b cmp $a} @files;
# tri numérique ascendant @articles = sort {$a <=> $b} @files;
# tri numérique descendant @articles = sort {$b <=> $a} @files;
# tri de %age par valeur plutôt que par clé # en utilisant une fonction en-ligne @eldest = sort { $age{$b} <=> $age{$a} } keys %age;
# tri utilisant le nom explicite d'une subroutine sub byage { $age{$a} <=> $age{$b}; # supposé numérique } @sortedclass = sort byage @class;
sub backwards { $b cmp $a; } @harry = qw(dog cat x Cain Abel); @george = qw(gone chased yz Punished Axed); print sort @harry; # affiche AbelCaincatdogx print sort backwards @harry; # affiche xdogcatCainAbel print sort @george, 'to', @harry; # affiche AbelAxedCainPunishedcatchaseddoggonetoxyz
# tri inefficace par ordre numérique descendant utilisant # le premier entier après le signe = ou l'ensemble de # l'enregistrement si cet entier n'existe pas
@new = sort { ($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0] || uc($a) cmp uc($b) } @old;
# la même chose mais plus efficace; # nous construisons un tableau auxilliaire d'indices # pour aller plus vite @nums = @caps = (); for (@old) { push @nums, /=(\d+)/; push @caps, uc($_); }
@new = @old[ sort { $nums[$b] <=> $nums[$a] || $caps[$a] cmp $caps[$b] } 0..$#old ];
# même chose sans utiliser de variables temporaires @new = map { $_->[0] } sort { $b->[1] <=> $a->[1] || $a->[2] cmp $b->[2] } map { [$_, /=(\d+)/, uc($_)] } @old;
# l'utilisation d'un prototype vous permet d'utiliser # n'importe quelle subroutine de comparaison comme # subroutine de tri (y compris des subroutines d'autres packages) package other; sub backwards ($$) { $_[1] cmp $_[0]; } # $a and $b are not set here
package main; @new = sort other::backwards @old;
Si vous utilisez strict, vous NE DEVEZ PAS déclarer $a et $b comme variables lexicales. Ce sont des variables globales au package. Cela signifie que si vous êtes dans le package "main", c'est :
@articles = sort {$main::b <=> $main::a} @files;
ou juste :
@articles = sort {$::b <=> $::a} @files;
mais si vous êtes dans le package "FooPack", <c'est :>
@articles = sort {$FooPack::b <=> $FooPack::a} @files;
La fonction de comparaison doit se comporter correctement. Si elle retourne des résultats incohérents (parfois elle dit que $x[1] est plus petit que $x[2] et d'autres fois le contraire par exemple), le résultat du tri n'est pas bien défini.
Les équivalences suivantes sont vraies en supposant que "$[ == 0" :
push(@a,$x,$y) splice(@a,@a,0,$x,$y) pop(@a) splice(@a,-1) shift(@a) splice(@a,0,1) unshift(@a,$x,$y) splice(@a,0,0,$x,$y) $a[$x] = $y splice(@a,$x,1,$y)
Exemple, en supposant que la longueur des tableaux est passée avant chaque tableau :
sub aeq { # compare deux listes de valeurs my(@a) = splice(@_,0,shift); my(@b) = splice(@_,0,shift); return 0 unless @a == @b; # même longueur ? while (@a) { return 0 if pop(@a) ne pop(@b); } return 1; } if (&aeq($len,@foo[1..$len],0+@bar,@bar)) { ... }
Si l'appel n'est pas dans un contexte de liste, split retourne le nombre de champs trouvés et les place dans le tableau @_. (Dans un contexte de liste, vous pouvez forcer l'utilisation du tableau @_ en utilisant "??" comme motif délimiteur mais il renvoie encore la liste des valeurs.) En revanche, l'utilisation implicite de @_ par split est désapprouvée parce que cela écrase les arguments de votre subroutine.
SI EXPR est omis, split découpe la chaîne $_. Si MOTIF est aussi omis, il découpe selon les blancs (après avoir sauté d'éventuels blancs au départ). Tout ce qui reconnu par MOTIF est considéré comme étant un délimiteur de champs. (Remarquez que le délimiteur peut être plus long qu'un seul caractère.)
SI LIMITE est spécifié et positif, fixe le nombre maximum de champs du découpage (il est possible que le nombre de champs soit inférieur). Si LIMITE n'est pas spécifié ou vaut zéro, les champs vides de la fin sont supprimés (chose dont les utilisateurs potentiels de "pop()" devraient se souvenir). Si LIMITE est négatif, il est traité comme si LIMITE avait une valeur arbitrairement très grande.
Un motif qui peut correspondre à la chaîne vide (ne pas confondre avec le motif vide "//" qui n'est qu'un motif parmi tous ceux qui peuvent correspondre à la chaîne vide) découpera la valeur de EXPR en caractère séparé à chaque point où il sera reconnu. Par exemple :
print join(':', split(/ */, 'hi there'));
produira la sortie 'h:i:t:h:e:r:e'.
La paramètre LIMITE peut être utilisé pour découper partiellement une ligne :
($login, $passwd, $remainder) = split(/:/, $_, 3);
Lors de l'affectation à une liste, si LIMITE est omis, Perl agit comme si LIMITE était égal au nombre de variables de la liste plus un pour éviter tout travail inutile. Pour la liste ci-dessous, la valeur par défaut de LIMITE serait 4. Dans les applications où le temps est critique, il vous incombe de ne pas découper en plus de champs que ceux réellement nécessaires.
Si MOTIF contient des parenthèses (et donc des sous-motifs), un élément supplémentaire est créé dans le tableau résultat pour chaque chaîne reconnue par le sous-motif.
split(/([,-])/, "1-10,20", 3);
produit la liste de valeurs
(1, '-', 10, ',', 20)
Si vous avez dans la variable $header tout l'en-tête d'un email normal d'UNIX, vous devriez pouvoir le découper en champs et valeurs en procédant comme suit :
$header =~ s/\n\s+/ /g; # fix continuation lines %hdrs = (UNIX_FROM => split /^(\S*?):\s*/m, $header);
Le motif "/MOTIF/" peut être remplacé par une expression pour spécifier un motif qui varie à chaque passage. (Pour faire une compilation une seule fois lors de l'exécution, utilisez "/$variable/o".)
Un cas spécial : spécifier un blanc (' ') comme MOTIF découpe selon les espaces exactement comme le fait "split()" sans argument. Donc, "split(' ')" peut être utilisé pour émuler le comportement par défaut de awk alors que "split(/ /)" vous donnera autant de champs vides que d'espaces au début. Un "split()" avec "/\s+/" est comme "split(' ')" sauf dans le cas de blancs au début qui produiront un premier champ vide. Un "split()" sans argument effectue réellement un "split(' ', $_)" en interne.
Exemple :
open(PASSWD, '/etc/passwd'); while (<PASSWD>) { ($login, $passwd, $uid, $gid, $gcos, $home, $shell) = split(/:/); #... }
(Remarquez que $shell contiendra encore un caractère de passage à la ligne (newline). Voir ``chop'', ``chomp'' et ``join''.)
Perl a sa propre implémentation de "sprintf()" --- elle émule la fonction C "sprintf()" mais elle ne l'utilise pas (sauf pour les nombres en virgule flottante, et encore en n'autorisant que les modificateurs standards). Conséquence : une extension non standard de votre version locale de "sprintf()" ne sera pas disponible en Perl.
Le "sprintf()" de Perl autorise les conversions universellement connues :
%% un signe pourcent %c un caractère dont on fournit le code %s une chaîne %d un entier signé, en décimal %u un entier non-signé, en décimal %o un entier non-signé, en octal %x un entier non-signé, en hexadécimal %e un nombre en virgule flottante, en notation scientifique %f un nombre en virgule flottante, avec un nombre de décimales fixe %g un nombre en virgule flottante, %e ou %f (au mieux)
De plus, Perl autorise les conversions largement supportées :
%X comme %x mais avec des lettres majuscules %E comme %e, mais en utilisant un "E" majuscule %G comme %g, mais en utilisant un "E" majuscule (si nécessaire) %b un entier non signé, en binaire %p un pointeur (affiche la valeur Perl de l'adresse en hexadécimal) %n spécial: stocke le nombre de caractères produits dans la prochaine variable de la liste des paramètres
Et finalement, pour des raisons de compatibilité (et ``uniquement'' pour cela), Perl autorise les conversions inutiles mais largement supportées :
%i un synonyme de %d %D un synonyme de %ld %U un synonyme de %lu %O un synonyme de %lo %F un synonyme de %f
Perl accepte les flags universellement connus suivants entre le "%" et la lettre de conversion :
espace précède les nombres positifs par un espace + précède les nombres positifs par un signe plus - justifie le champ à gauche 0 utilise des zéros à la place des espaces pour justifier à droite # précède le nombre non nul en octal par "0", précède le nombre non nul en hexadécimal par "0x" nombre taille minimum du champ .nombre "précision": nombre de décimales pour un nombre en virgule flottante, longueur maximum pour une chaîne, longueur minimum pour un entier l interprète un entier comme le type C "long" ou "unsigned long" h interprète un entier comme le type C "short" ou "unsigned short"
Il y a aussi deux flags spécifiques à Perl :
V interprète un entier comme le type entier standard de Perl v interprète la chaîne comme un vecteur d'entiers. Affichera ces entiers séparés par des points ou par une chaîne arbitraire reçue dans la liste des arguments si le flag est précédé de C<*>
À chaque fois qu'un nombre peut être spécifié comme flag, on peut le remplacer par un astérisque (""*"``) auquel cas Perl utilise le prochain item de la liste des paramètres comme valeur pour ce nombre (c'est à dire comme longueur ou précision du champ). Si un champ de longueur obtenu par ''"*"`` est négatif alors cela a le même effet que le flag ''"-"" : justification à gauche.
Le flag "v" est pratique pour afficher les valeurs représentées par des caractères dans une chaîne arbitraire :
printf "version is v%vd\n", $^V; # version de Perl printf "address is %*vX\n", ":", $addr; # adresse IPv6 printf "bits are %*vb\n", " ", $bits; # chaîne de bits aléatoire
Si "use locale" est actif, le caractère utilisé comme séparateur décimal pour les nombres réels dépend de la valeur de LC_NUMERIC. Voir perllocale.
Si Perl comprend les ``quads'' (les entiers sur 64-bit) (cela nécessite soit que la plate-forme native supporte les quads soit que Perl a été compilé spécifiquement pour supporté les quads), les caractères :
d u o x X b i D U O
affiche des quads et ils peuvent être précédé par :
ll L q
Par exemple :
%lld %16LX %qo
Vous pouvez savoir si Perl supporte les long doubles via Config :
use Config; $Config{d_longdbl} eq 'define' && print "long doubles\n";
use Math::Complex; print sqrt(-2); # affiche 1.4142135623731i
En fait, il n'est même plus nécessaire d'appeler "srand()" puisque s'il n'est pas appelé explicitement, il l'est implicitement lors de la première utilisation de l'opérateur "rand()". Par contre, ce n'était pas le cas dans les versions de Perl antérieures à la version 5.004 et donc, si votre script doit pouvoir tourner avec de vieilles versions de Perl, il doit appeler "srand()".
Remarque : vous devez utiliser quelque chose de beaucoup plus aléatoire que la graine par défaut pour des applications de cryptographie. Le checksum d'une sortie compressée d'un ou plusieurs programmes système dont les valeurs changent rapidement est une méthode usuelle. Par exemple :
srand (time ^ $$ ^ unpack "%L*", `ps axww | gzip`);
Si cela vous intéresse tout particulièrement, regardez le module CPAN "Math::TrulyRandom".
N'appelez pas "srand()" plusieurs fois dans votre programme à moins de savoir exactement ce que vous faites et pourquoi vous le faites. L'objectif de cette fonction est d'initialiser la fonction "rand()" afin qu'elle produise une séquence différente à chaque exécution de votre programme. Faites-le une bonne fois pour toutes au début de votre programme ou "rand()" ne vous produira pas des nombres aléatoires.
Les programmes fréquemment utilisés (comme des scripts CGI) qui utilisent simplement :
time ^ $$
comme graine peuvent tomber sur la propriété mathématique suivante :
a^b == (a+1)^(b+1)
une fois sur trois. Donc ne faites pas ça.
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
Certains champs ne sont pas gérés par certains types de systèmes de fichiers. Voici la signification de ces champs :
0 dev numéro de device du système de fichiers 1 ino numéro d'inode 2 mode droits du fichier (type et permissions) 3 nlink nombre de liens (hard) sur le fichier 4 uid ID numérique de l'utilisateur propriétaire du fichier 5 gid ID numérique du groupe propriétaire du fichier 6 rdev l'identificateur de device (fichiers spéciaux uniquement) 7 size taille totale du fichier, en octets 8 atime date de dernier accès en secondes depuis l'origine des temps 9 mtime date de dernière modification en secondes depuis l'origine des temps 10 ctime date de dernière modification de l'inode (pas la date de création) en secondes depuis l'origine des temps 11 blksize taille de blocs préférée pour les E/S sur fichiers 12 blocks nombre de blocs réellement occupés
(Sur la plupart des systèmes, l'origine des temps est fixé au 1er janvier 1970 à minuit GMT.)
Si vous passez à stat le descripteur spécial dont le nom est le caractère souligné seul, aucun appel à stat n'est effectué par contre le contenu courant de la structure d'état du dernier appel à stat ou du dernier test de fichier est retourné. Exemple :
if (-x $file && (($d) = stat(_)) && $d < 0) { print "$file is executable NFS file\n"; }
(Ceci ne marche que sur les machines dont le numéro de device est négatif sous NFS.)
Comme le mode contient à la fois le type de fichier et les droits d'accès, vous devrez masquer la portion concernant le type de fichier et utiliser (s)printf avec le format "%o" pour voir les véritables permissions :
$mode = (stat($filename))[2]; printf "Permissions are %04o\n", $mode & 07777;
Dans un contexte scalaire, "stat()" retourne une valeur booléenne indiquant le succès ou l'échec et positionne, en cas de succès, les informations lié au descripteur spécial "_".
Le module File::stat fournit un mécanisme pratique d'accès par nom :
use File::stat; $sb = stat($filename); printf "File is %s, size is %s, perm %04o, mtime %s\n", $filename, $sb->size, $sb->mode & 07777, scalar localtime $sb->mtime;
Vous pouvez importer les constantes symboliques de permissions ("S_IF*") et les fonctions de test ("S_IS*") depuis le module Fcntl :
use Fcntl ':mode';
$mode = (stat($filename))[2];
$user_rwx = ($mode & S_IRWXU) >> 6; $group_read = ($mode & S_IRGRP) >> 3; $other_execute = $mode & S_IXOTH;
printf "Permissions are %04o\n", S_ISMODE($mode), "\n";
$is_setuid = $mode & S_ISUID; $is_setgid = S_ISDIR($mode);
Vous pourriez écrire ces deux derniers exemples en utilisant les opérateurs "-u" et "-d". Les constantes communes disponibles sont :
# Droits : lecture, écriture, exécution, # pour utilisateur, groupe, autres.
S_IRWXU S_IRUSR S_IWUSR S_IXUSR S_IRWXG S_IRGRP S_IWGRP S_IXGRP S_IRWXO S_IROTH S_IWOTH S_IXOTH
# Setuid/Setgid/Stickiness.
S_ISUID S_ISGID S_ISVTX S_ISTXT
# File types. Not necessarily all are available on your system.
S_IFREG S_IFDIR S_IFLNK S_IFBLK S_ISCHR S_IFIFO S_IFSOCK S_IFWHT S_ENFMT
# The following are compatibility aliases for S_IRUSR, S_IWUSR, S_IXUSR.
S_IREAD S_IWRITE S_IEXEC
et les fonctions S_IF* <sont :>
S_IFMODE($mode) the part of $mode containg the permission bits and the setuid/setgid/sticky bits
S_IFMT($mode) the part of $mode containing the file type which can be bit-anded with e.g. S_IFREG or with the following functions
# The operators -f, -d, -l, -b, -c, -p, and -s.
S_ISREG($mode) S_ISDIR($mode) S_ISLNK($mode) S_ISBLK($mode) S_ISCHR($mode) S_ISFIFO($mode) S_ISSOCK($mode)
# No direct -X operator counterpart, but for the first one # the -g operator is often equivalent. The ENFMT stands for # record flocking enforcement, a platform-dependent feature.
S_ISENFMT($mode) S_ISWHT($mode)
Voir la documentation native de chmod(2) et de stat(2) pour de meilleures informations au sujet des constantes S_*.
Par exemple : voici la boucle qui insère une entrée d'index devant chaque ligne contenant un certain motif :
while (<>) { study; print ".IX foo\n" if /\bfoo\b/; print ".IX bar\n" if /\bbar\b/; print ".IX blurfl\n" if /\bblurfl\b/; # ... print; }
Lors de la recherche de "/\bfoo\b/", seuls sont examinés les endroits de $_ contenant "f" parce que "f" est plus rare que "o". En général, le gain est important sauf dans des cas pathologiques. Savoir si l'étude initiale est moins coûteuse que le temps gagné lors de la recherche est la seule vraie question.
Remarquez que si vous faites une recherche sur des chaînes que vous ne connaissez que lors de l'exécution, vous pouvez alors construire une boucle entière dans une chaîne que vous évaluerez via "eval()" afin d'éviter de recompiler vos motifs à chaque passage. Combiné avec l'affectation de undef à $/ pour lire chaque fichier comme un seul enregistrement, cela peut être extrêmement rapide et parfois même plus rapide que des programmes spécialisés comme fgrep(1). Le code suivant recherche une liste de mots (@words) dans une liste de fichiers (@files) et affiche la liste des fichiers qui contiennent ces mots :
$search = 'while (<>) { study;'; foreach $word (@words) { $search .= "++\$seen{\$ARGV} if /\\b$word\\b/;\n"; } $search .= "}"; @ARGV = @files; undef $/; eval $search; # ca parle... $/ = "\n"; # retour au délimiteur de ligne normal foreach $file (sort keys(%seen)) { print $file, "\n"; }
Vous pouvez utiliser la fonction "substr()" comme une lvalue auquel cas EXPR doit aussi être une lvalue. Si vous affectez quelque chose de plus court que LONGUEUR, la chaîne raccourcit et si vous affectez quelque chose de plus long que LONGUEUR, la chaîne grossit. Pour conserver la même longueur vous pouvez remplir ou couper votre valeur en utilisant "sprintf()".
Si OFFSET et LONGUEUR spécifient une sous-chaîne qui est partiellement en dehors de la chaîne, seule la partie qui est dans la chaîne qui est retournée. Si la sous-chaîne est entièrement en dehors de la chaîne, un message d'avertissement (warning) est produit et la valeur undef est retournée. Lorsque substr() est utilisé en tant que lvalue, spécifier une sous-chaîne entièrement en dehors de la chaîne produit une erreur fatale. Voici un exemple illustrant ce comportement :
my $name = 'fred'; substr($name, 4) = 'dy'; # $name vaut maintenant 'freddy' my $null = substr $name, 6, 2; # retourne '' (sans avertissement) my $oops = substr $name, 7; # retourne undef, avec avertissement substr($name, 7) = 'gap'; # erreur fatale
Un autre moyen d'utiliser "substr()" comme lvalue est de spécifier la chaîne de remplacement comme quatrième argument (REMPLACEMENT). Ceci permet de remplacer une partie de la chaîne en récupérant ce qui y était auparavant en une seule opération exactement comme avec splice().
$symlink_exists = eval { symlink("",""); 1 };
require 'syscall.ph'; # peut nécessiter de faire tourner h2ph $s = "hi there\n"; syscall(&SYS_write, fileno(STDOUT), $s, length $s);
Remarquez que Perl ne peut pas passer plus de 14 arguments à votre appel système, ce qui en pratique suffit largement.
Syscall retourne la valeur retournée par l'appel système appelé. Si l'appel système échoue, "syscall()" retourne "-1" et positionne $! (errno). Remarquez que certains appels systèmes peuvent légitimement retourner "-1". Le seul moyen de gérer cela proprement est de faire "$!=0" avant l'appel système et de regarder la valeur de $! lorsque syscall retourne "-1".
Il y a un problème avec "syscall(&SYS_pipe)" : cela retourne le numéro du fichier créé côté lecture du tube. Il n'y a aucun moyen de récupérer le numéro de fichier de l'autre côté. Vous pouvez contourner ce problème en utilisant "pipe()" à la place.
Les valeurs possibles des bits du paramètre MODE sont dépendantes du système ; elles sont disponibles via le module standard "Fcntl". Lisez la documentation du "open" de votre système d'exploitation pour savoir quels sont les bits disponibles. Vous pouvez combiner plusieurs valeurs en utilisant l'opérateur "|".
Quelques-unes des valeurs les plus courantes sont "O_RDONLY" pour l'ouverture en lecture seule, "O_WRONLY" pour l'ouverture en écriture seule, et "O_RDWR" pour l'ouverture en mode lecture/écriture.
Pour des raisons historiques, quelques valeurs fonctionnent sur la plupart des systèmes supportés par perl : zéro signifie lecture seule, un signifie écriture seule et deux signifie lecture/écriture. Nous savons que ces valeurs ne fonctionne pas sous Unix OS/390 ou sur Macintosh ; vous ne devriez sans doute pas les utiliser dans du code nouveau.
Si le fichier nommé FILENAME n'existe pas et que l'appel à "open()" le crée (typiquement parce que MODE inclut le flag "O_CREAT") alors la valeur de PERM spécifie les droits de ce nouveau fichier. Si vous avez omis l'argument PERM de "sysopen()", Perl utilise la valeur octale 0666. Les valeurs de droits doivent être fournies en octal et sont modifiées par la valeur courante du "umask" de votre process.
Sur la plupart des systèmes, le flag "O_EXCL" permet d'ouvrir un fichier en mode exclusif. Ce n'est pas du verrouillage : l'exclusivité signifie ici que si le fichier existe déjà, sysopen() échoue. "O_EXCL" l'emporte sur "O_TRUNC".
Parfois vous voudrez tronqué un fichier existant : "O_TRUNC".
Vous devriez éviter d'imposer un mode 0644 comme argument de "sysopen" parce que cela enlève à l'utilisateur la possibilité de fixer un umask plus permissif. Voir ``umask'' pour plus de détails.
Notez que "sysopen" dépend de la fonction fdopen() de votre bibliothèque C. Sur de nombreux systèmes UNIX, fdopen() est connue pour échouer si le nombre de descripteurs de fichiers excède une certaine valeur, typiquement 255. Si vous avez besoin de plus de descripteurs, pensez à recompiler Perl en utilisant la bibliothèque "sfio" ou à utiliser le fonction POSIX::open().
Voir perlopentut pour une initiation à l'ouverture de fichiers.
Un OFFSET peut être spécifié pour placer les données lues ailleurs qu'au début de la chaîne. Un OFFSET négatif spécifie un emplacement en comptant à partir de la fin de la chaîne. Un OFFSET positif plus grand que la longueur de SCALAIRE agrandira la chaîne jusqu'à la taille requise en la remplissant avec des octets "\0" avant de lui ajouter le résultat de la lecture.
Il n'y a pas de fonction syseof(), ce qui n'est pas un mal puisque eof() ne marche pas très bien sur les fichiers device (comme les tty). Utilisez sysread() et testez une valeur de retour à zéro pour savoir si c'est terminé.
Retourne la nouvelle position ou undef en cas d'échec. Une position nulle est retournée par la valeur "0 but true" ; Donc "sysseek()" retourne true (vrai) en cas de succès et false (faux) en cas d'échec et vous pouvez encore déterminer facilement la nouvelle position.
Depuis la version v5.6.0, Perl tente de vider les tampons de tous les fichiers ouverts en écriture avant d'effectuer une opération impliquant un fork() mais cela n'est pas supporté sur toutes les plates-formes (voir perlport). Pour être plus sûr, vous devriez positionner la variable $| ($AUTOFLUSH en anglais) ou appelé la méthode "autoflush()" des objets "IO::Handle" pour chacun des descripteurs ouverts.
La valeur retournée est le statut de sortie (exit status) du programme tel que retourné par l'appel "wait()". Pour obtenir la valeur réelle de sortie, il faut le diviser par 256. Voir aussi ``exec''. Ce n'est pas ce qu'il faut utiliser pour capturer la sortie d'une commande. Pour cela, regarder les apostrophes inversées (backticks) ou "qx//" comme décrit dans ```CHAINE`'' in perlop. Une valeur de retour "-1" indique l'échec du lancement du programme ($! en donne la raison).
Comme "exec()", "system()" vous autorise à définir le nom sous lequel le programme apparaît si vous utilisez la syntaxe ""system PROGRAMME LISTE"". Voir ``exec''.
Puisque "system()" et les apostrophes inversées (backticks) bloquent "SIGINT" et "SIGQUIT", tuer le programme qu'ils font tourner n'interrompra pas votre programme.
@args = ("command", "arg1", "arg2"); system(@args) == 0 or die "system @args failed: $?"
Vous pouvez tester tous les cas possibles d'échec en analysant $? de la manière suivante :
$exit_value = $? >> 8; $signal_num = $? & 127; $dumped_core = $? & 128;
Lorsque les arguments sont exécutés via le shell système, les résultats et codes de retour sont sujet à tous ses caprices et capacités. Voir ```CHAINE`'' in perlop et ``exec'' pour plus de détails.
Un OFFSET peut être spécifié pour lire les données à écrire à partir d'autre chose que le début du scalaire. Un OFFSET négatif calcule l'emplacement en comptant à partir de la fin de la chaîne. Au cas où SCALAIRE est vide, vous pouvez utiliser OFFSET mais uniquement avec la valeur zéro.
Il n'y a pas de fonction "systell". Utilisez "sysseek(FH, 0, 1)" à la place.
Remarquez que des fonctions telles que "keys()" et "values()" peuvent retourner des listes énormes lorsqu'elles sont utilisées sur de gros objets comme des fichiers DBM. Vous devriez plutôt utiliser la fonction "each()" pour les parcourir. Exemple :
# print out history file offsets use NDBM_File; tie(%HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0); while (($key,$val) = each %HIST) { print $key, ' = ', unpack('L',$val), "\n"; } untie(%HIST);
Une classe implémentant une table de hachage devrait définir les méthodes suivantes :
TIEHASH classname, LISTE FETCH this, key STORE this, key, value DELETE this, key CLEAR this EXISTS this, key FIRSTKEY this NEXTKEY this, lastkey DESTROY this
Une classe implémentant un tableau devrait définir les méthodes suivantes :
TIEARRAY classname, LISTE FETCH this, key STORE this, key, value FETCHSIZE this STORESIZE this, count CLEAR this PUSH this, LISTE POP this SHIFT this UNSHIFT this, LISTE SPLICE this, offset, length, LISTE EXTEND this, count DESTROY this
Une classe implémentant un descripteur de fichier devrait définir les méthodes suivantes :
TIEHANDLE classname, LISTE READ this, scalar, length, offset READLINE this GETC this WRITE this, scalar, length, offset PRINT this, LISTE PRINTF this, format, LISTE CLOSE this DESTROY this
Une classe implémentant un scalaire devrait définir les méthodes suivantes :
TIESCALAR classname, LISTE DESTROY this FETCH this, STORE this, value
Il n'est pas absolument nécessaire d'implémenter toutes les méthodes décrites ci-dessus. Voir perltie, Tie::Hash, Tie::Array, Tie::Scalar, et Tie::Handle.
Au contraire de "dbmopen()", la fonction "tie()" n'effectue pas pour vous le 'use' ou le 'require' du module --- vous devez le faire vous-même explicitement. Voir les modules DB_File ou Config pour des utilisations intéressantes de "tie()".
Pour de plus amples informations, voir perltie et ``tied VARIABLE''.
Pour mesurer le temps avec une meilleure granularité que la seconde, vous pouvez utiliser le module Time::HiRes disponible sur CPAN ou, si vous avec gettimeofday(2), vous pouvez utiliser l'interface "syscall" de Perl. Voir perlfaq8 pour les détails.
($user,$system,$cuser,$csystem) = times;
Si EXPR est omis, s'applique à $_.
Si EXPR est omis, s'applique à $_.
Les droits Unix "rwxr-x---" sont représentés par trois ensembles de trois bits ou par trois nombres octaux : 0750 (le 0 initial indique une valeur octale et ne fait pas partie des chiffres). La valeur de "umask" est un tel nombre qui représente les bits de permissions désactivés. Les valeurs de permissions (ou ``droits'' ou ``mode'') que vous passez à "mkdir" ou "sysopen" sont modifiées par votre umask. Par exemple, si vous dites à "sysopen" de créer un fichier avec les droits 0777 et si votre umask vaut 0022 alors le fichier sera réellement créé avec les droits 0755. Si votre umask vaut 0027 (le groupe ne peut écrire ; les autres ne peuvent ni lire, ni écrire, ni exécuter) alors passer 0666 à "sysopen" créera une fichier avec les droits 0640 ("0666 &~ 027" vaut 0640).
Voici quelques conseils : fournissez un mode de création de 0666 pour les fichiers normaux (dans "sysopen") et de 0777 pour les répertoires (dans "mkdir") et les fichiers exécutables. Cela donne la liberté à l'utilisateur de choisir : si il veut des fichiers protégés, il peut choisir un umask de 022 ou 027 ou même le umask particulièrement antisocial 077. Les programmes peuvent rarement (si ce n'est jamais) prendre des décisions de politique meilleures que l'utilisateur. L'exception concerne les fichiers qui doivent être gardés privé : fichiers de mail, fichiers de cookies des navigateurs, fichiers .rhosts et autres.
Si umask(2) n'est pas implémenté sur votre système et que vous êtes en train de restreindre les droits d'accès pour vous-même (i.e. (EXPR & 0700) > 0), cela produit une erreur fatale lors de l'exécution. Si umask(2) n'est pas implémenté et que vous ne modifiez pas vos propres droits d'accès, retourne "undef".
Souvenez-vous que umask est un nombre, habituellement donné en octal ; Ce n'est pas une chaîne de chiffres en octal. Voir aussi ``oct'', si vous disposez d'une chaîne.
undef $foo; undef $bar{'blurfl'}; # À comparer à : delete $bar{'blurfl'}; undef @ary; undef %hash; undef &mysub; undef *xyz; # détruit $xyz, @xyz, %xyz, &xyz, etc. return (wantarray ? (undef, $errmsg) : undef) if $they_blew_it; select undef, undef, undef, 0.25; ($a, $b, undef, $c) = &foo; # Ignorer la troisième valeur retournée
Remarquez que c'est un opérateur unaire et non un opérateur de liste.
$cnt = unlink 'a', 'b', 'c'; unlink @goners; unlink <*.bak>;
Remarque : "unlink()" n'effacera pas de répertoires à moins que vous ne soyez le super-utilisateur (root) et que l'option -U soit donnée à Perl. Même si ces conditions sont remplies, soyez conscient que l'effacement d'un répertoire par unlink peut endommager votre système de fichiers. Utilisez "rmdir()" à la place.
Si LISTE est omis, s'applique à $_.
La chaîne est découpé en morceaux selon le format TEMPLATE fourni. Chaque morceau est converti séparément en une valeur. Typiquement, soit la chaîne est le résultat d'un "pack" soit les octets de la chaîne représentent un structure C d'un certain type.
Le TEMPLATE a le même format que pour la fonction "pack()". Voici une subroutine qui extrait une sous-chaîne :
sub substr { my($what,$where,$howmuch) = @_; unpack("x$where a$howmuch", $what); }
et un autre exemple :
sub ordinal { unpack("c",$_[0]); } # identique à ord()
En plus, vous pouvez préfixer un champ avec un %<nombre> pour indiquer que vous voulez un checksum des items sur <nombre> bits à la place des items eux-mêmes. Par défaut, c'est un checksum sur 16 bits. Le checksum est calculé en additionnant les valeurs numériques des valeurs extraites (pour les champs alphanumériques, c'est la somme des "ord($caractere)" qui est prise et pour les champs de bits, c'est la somme des 1 et des 0).
Par exemple, le code suivant calcule le même nombre que le programme sum System V :
$checksum = do { local $/; # slurp! unpack("%32C*",<>) % 65535; };
Le code suivant calcule de manière efficace le nombre de bits à un dans un vecteur de bits :
$setbits = unpack("%32b*", $selectmask);
Les formats "p" et "P" doivent être utilisés avec précautions. Puisque Perl n'a aucun moyen de vérifier que les valeurs passées à "unpack()" correspondent à des emplacements mémoires valides, le passage d'un pointeur dont on n'est pas sûr de la validité peut avoir des conséquences désastreuses.
Si la valeur de répétition d'un champ est plus grande que ce que le reste de la chaîne d'entrée autorise, la valeur est diminuée. Si la chaîne d'entrée est plus longue que ce qui est décrit par TEMPLATE, le reste est ignoré.
Voir ``pack'' pour plus d'exemples et de remarques.
unshift(ARGV, '-e') unless $ARGV[0] =~ /^-/;
Remarquez que LISTE est ajoutée d'un seul coup et non élément par élément. Donc les éléments restent dans le même ordre. Utilisez "reverse()" pour faire le contraire.
BEGIN { require Module; import Module LISTE; }
sauf que Module doit être un mot (bareword).
VERSION, qui peut être spécifié sous la forme v5.6.1, demande que la version courante de Perl ($^V ou $PERL_VERSION) soit au moins aussi récente que VERSION. (Pour des raisons de compatibilité avec de vieilles versions Perl, un littéral numérique sera aussi interprété comme une VERSION.) Si la version de l'interpréteur Perl courant est plus petite que VERSION alors un message est affiché et Perl se termine immédiatement sans même essayer de lire le reste du fichier. Comparez avec ``require'' qui peut faire la même chose mais lors de l'exécution.
use v5.6.1; # vérification de version à la compilation use 5.6.1; # idem use 5.005_03; # numéro de version numérique
C'est pratique si vous devez vérifier la version courante de Perl avant d'utiliser (via "use") des modules qui ont changé de manière incompatible depuis les anciennes versions. (Nous essayons de le faire le moins souvent possible).
Le "BEGIN" force le "require" et le "import" lors de la compilation. Le "require" assure que le module est chargé en mémoire si il ne l'avait pas déjà été. "import" n'est pas une fonction interne --- c'est juste un appel à une méthode statique ordinaire dans le package ""Module"" pour lui demander d'importer dans le package courant la liste de ses fonctionnalités. Le module peut implémenter sa méthode "import()" comme il le veut, bien que la plupart des modules préfèrent simplement la définir par héritage de la classe "Exporter" qui est définie dans le module "Exporter". Voir Exporter. Si aucune méthode "import()" ne peut être trouvée alors l'appel est ignoré.
Si vous ne voulez pas que votre espace de noms soit modifié, fournissez explicitement une liste vide :
use Module ();
C'est exactement équivalent à :
BEGIN { require Module }
Si l'argument VERSION est présent entre Module et LISTE alors "use" appelle le méthode VERSION de la classe Module avec la version spécifié comme argument. La méthode VERSION par défaut, héritée de la classe Universal, crie (via croak) si la version demandée est plus grande que celle fournie par la variable $Module::VERSION. Remarquez qu'il n'y a pas de virgule après VERSION !
À nouveau, il y a une différence entre omettre LISTE ("import" appelé sans argument) et fournir une LISTE explicitement vide "()" ("import" n'est pas appelé).
Puisque c'est une interface largement ouverte, les pragmas (les directives du compilateur) sont aussi implémentés en utilisant ce moyen. Les pragmas actuellement implémentés sont :
use integer; use diagnostics; use sigtrap qw(SEGV BUS); use strict qw(subs vars refs); use subs qw(afunc blurfl); use warnings qw(all);
Certains d'entre eux sont des pseudo-modules qui importent de nouvelles sémantiques uniquement dans la portée du bloc courant (comme "strict" or "integer") contrairement aux modules ordinaires qui importent des symboles dans le package courant (qui sont donc effectifs jusqu'à la fin du fichier lui-même).
Il y a une commande ""no"`` permettant de ''désimporter" des choses importées par "use", i.e. elle appelle "unimport Module LISTE" à la place de "import".
no integer; no strict 'refs'; no warnings;
Si aucune méthode "unimport()" ne peut être trouvée l'appel échoue avec une erreur fatale.
Voir perlmod pour une liste des modules et pragmas standard.
#!/usr/bin/perl $now = time; utime $now, $now, @ARGV;
Remarquez que vous ne pouvez pas changer les valeurs de la table par ce moyen car la liste retournée est juste une copie des valeurs. Vous devez utilisez un slice de table de hachage pour cela puisqu'il produit une lvalue alors que values() ne l'est pas.
for (values %hash) { s/foo/bar/g } # ECHEC ! for (@hash{keys %hash}) { s/foo/bar/g } # ok
Comme effet de bord, il réinitialise l'itérateur de HASH. Voir aussi "keys", "each" et "sort".
Si BITS vaut 8, les ``éléments'' coïncident avec les octets de la chaîne d'entrée.
Si BITS vaut 16 ou plus, les octets de la chaîne d'entrée sont groupés par morceau de taille BITS/8 puis chaque groupe est converti en un nombre comme le feraient pack() et unpack() avec les formats big-endian "n"/"N". Voir ``pack'' pour plus de détails.
Si BITS est 4 ou moins, la chaîne est découpée en octets puis les bits de chaque octet sont découpés en 8/BITS groupes. Les bits d'un octet sont numérotés à la manière little-endian comme dans 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80. Par exemple, le découpage d'un seul octet d'entrée "chr(0x36)" en deux groupes donnera la liste "(0x6, 0x3)" ; son découpage en 4 groupes donnera "(0x2, 0x1, 0x3, 0x0)".
"vec()" peut aussi être affecté auquel cas les parenthèses sont nécessaires pour donner les bonnes priorités :
vec($image, $max_x * $x + $y, 8) = 3;
Si l'élément sélectionné est en dehors de la chaîne, la valeur retournée sera zéro. Si, au contraire, vous cherchez à écrire dans un élément en dehors de la chaîne, Perl agrandira suffisamment la chaîne au préalable en la complétant par des octets nuls.
Les vecteurs créés par "vec()" peuvent aussi être manipulés par les opérateurs logiques "|", "&" et "^" qui supposent qu'une opération bit à bit est voulue lorsque leurs deux opérandes sont des chaînes. Voir ``Opérateurs bit à bit sur les chaînes'' in perlop.
Le code suivant construit une chaîne ASCII disant 'PerlPerlPerl'. Les commentaires montrent la chaîne après chaque pas. Remarquez que ce code fonctionne de la même manière sur des machines big-endian ou little-endian.
my $foo = ''; vec($foo, 0, 32) = 0x5065726C; # 'Perl'
# $foo eq "Perl" eq "\x50\x65\x72\x6C", 32 bits print vec($foo, 0, 8); # affiche 80 == 0x50 == ord('P')
vec($foo, 2, 16) = 0x5065; # 'PerlPe' vec($foo, 3, 16) = 0x726C; # 'PerlPerl' vec($foo, 8, 8) = 0x50; # 'PerlPerlP' vec($foo, 9, 8) = 0x65; # 'PerlPerlPe' vec($foo, 20, 4) = 2; # 'PerlPerlPe' . "\x02" vec($foo, 21, 4) = 7; # 'PerlPerlPer' # 'r' is "\x72" vec($foo, 45, 2) = 3; # 'PerlPerlPer' . "\x0c" vec($foo, 93, 1) = 1; # 'PerlPerlPer' . "\x2c" vec($foo, 94, 1) = 1; # 'PerlPerlPerl' # 'l' is "\x6c"
Pour transformer un vecteur de bits en une chaîne ou en un tableau de 0 et de 1, utilisez ceci :
$bits = unpack("b*", $vector); @bits = split(//, unpack("b*", $vector));
Si vous connaissez précisément la longueur du vecteur, vous pouvez l'utiliser à la place de "*".
Voici un exemple qui illustre comment le bits sont réellement placés :
#!/usr/bin/perl -wl
print <<'EOT'; 0 1 2 3 unpack("V",$_) 01234567890123456789012345678901 ------------------------------------------------------------------ EOT
for $w (0..3) { $width = 2**$w; for ($shift=0; $shift < $width; ++$shift) { for ($off=0; $off < 32/$width; ++$off) { $str = pack("B*", "0"x32); $bits = (1<<$shift); vec($str, $off, $width) = $bits; $res = unpack("b*",$str); $val = unpack("V", $str); write; } } }
format STDOUT = vec($_,@#,@#) = @<< == @######### @>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> $off, $width, $bits, $val, $res . __END__
Indépendamment de l'architecture de la machine qui exécute ce code, l'exemple ci-dessus devrait produire la table suivante :
0 1 2 3 unpack("V",$_) 01234567890123456789012345678901 ------------------------------------------------------------------ vec($_, 0, 1) = 1 == 1 10000000000000000000000000000000 vec($_, 1, 1) = 1 == 2 01000000000000000000000000000000 vec($_, 2, 1) = 1 == 4 00100000000000000000000000000000 vec($_, 3, 1) = 1 == 8 00010000000000000000000000000000 vec($_, 4, 1) = 1 == 16 00001000000000000000000000000000 vec($_, 5, 1) = 1 == 32 00000100000000000000000000000000 vec($_, 6, 1) = 1 == 64 00000010000000000000000000000000 vec($_, 7, 1) = 1 == 128 00000001000000000000000000000000 vec($_, 8, 1) = 1 == 256 00000000100000000000000000000000 vec($_, 9, 1) = 1 == 512 00000000010000000000000000000000 vec($_,10, 1) = 1 == 1024 00000000001000000000000000000000 vec($_,11, 1) = 1 == 2048 00000000000100000000000000000000 vec($_,12, 1) = 1 == 4096 00000000000010000000000000000000 vec($_,13, 1) = 1 == 8192 00000000000001000000000000000000 vec($_,14, 1) = 1 == 16384 00000000000000100000000000000000 vec($_,15, 1) = 1 == 32768 00000000000000010000000000000000 vec($_,16, 1) = 1 == 65536 00000000000000001000000000000000 vec($_,17, 1) = 1 == 131072 00000000000000000100000000000000 vec($_,18, 1) = 1 == 262144 00000000000000000010000000000000 vec($_,19, 1) = 1 == 524288 00000000000000000001000000000000 vec($_,20, 1) = 1 == 1048576 00000000000000000000100000000000 vec($_,21, 1) = 1 == 2097152 00000000000000000000010000000000 vec($_,22, 1) = 1 == 4194304 00000000000000000000001000000000 vec($_,23, 1) = 1 == 8388608 00000000000000000000000100000000 vec($_,24, 1) = 1 == 16777216 00000000000000000000000010000000 vec($_,25, 1) = 1 == 33554432 00000000000000000000000001000000 vec($_,26, 1) = 1 == 67108864 00000000000000000000000000100000 vec($_,27, 1) = 1 == 134217728 00000000000000000000000000010000 vec($_,28, 1) = 1 == 268435456 00000000000000000000000000001000 vec($_,29, 1) = 1 == 536870912 00000000000000000000000000000100 vec($_,30, 1) = 1 == 1073741824 00000000000000000000000000000010 vec($_,31, 1) = 1 == 2147483648 00000000000000000000000000000001 vec($_, 0, 2) = 1 == 1 10000000000000000000000000000000 vec($_, 1, 2) = 1 == 4 00100000000000000000000000000000 vec($_, 2, 2) = 1 == 16 00001000000000000000000000000000 vec($_, 3, 2) = 1 == 64 00000010000000000000000000000000 vec($_, 4, 2) = 1 == 256 00000000100000000000000000000000 vec($_, 5, 2) = 1 == 1024 00000000001000000000000000000000 vec($_, 6, 2) = 1 == 4096 00000000000010000000000000000000 vec($_, 7, 2) = 1 == 16384 00000000000000100000000000000000 vec($_, 8, 2) = 1 == 65536 00000000000000001000000000000000 vec($_, 9, 2) = 1 == 262144 00000000000000000010000000000000 vec($_,10, 2) = 1 == 1048576 00000000000000000000100000000000 vec($_,11, 2) = 1 == 4194304 00000000000000000000001000000000 vec($_,12, 2) = 1 == 16777216 00000000000000000000000010000000 vec($_,13, 2) = 1 == 67108864 00000000000000000000000000100000 vec($_,14, 2) = 1 == 268435456 00000000000000000000000000001000 vec($_,15, 2) = 1 == 1073741824 00000000000000000000000000000010 vec($_, 0, 2) = 2 == 2 01000000000000000000000000000000 vec($_, 1, 2) = 2 == 8 00010000000000000000000000000000 vec($_, 2, 2) = 2 == 32 00000100000000000000000000000000 vec($_, 3, 2) = 2 == 128 00000001000000000000000000000000 vec($_, 4, 2) = 2 == 512 00000000010000000000000000000000 vec($_, 5, 2) = 2 == 2048 00000000000100000000000000000000 vec($_, 6, 2) = 2 == 8192 00000000000001000000000000000000 vec($_, 7, 2) = 2 == 32768 00000000000000010000000000000000 vec($_, 8, 2) = 2 == 131072 00000000000000000100000000000000 vec($_, 9, 2) = 2 == 524288 00000000000000000001000000000000 vec($_,10, 2) = 2 == 2097152 00000000000000000000010000000000 vec($_,11, 2) = 2 == 8388608 00000000000000000000000100000000 vec($_,12, 2) = 2 == 33554432 00000000000000000000000001000000 vec($_,13, 2) = 2 == 134217728 00000000000000000000000000010000 vec($_,14, 2) = 2 == 536870912 00000000000000000000000000000100 vec($_,15, 2) = 2 == 2147483648 00000000000000000000000000000001 vec($_, 0, 4) = 1 == 1 10000000000000000000000000000000 vec($_, 1, 4) = 1 == 16 00001000000000000000000000000000 vec($_, 2, 4) = 1 == 256 00000000100000000000000000000000 vec($_, 3, 4) = 1 == 4096 00000000000010000000000000000000 vec($_, 4, 4) = 1 == 65536 00000000000000001000000000000000 vec($_, 5, 4) = 1 == 1048576 00000000000000000000100000000000 vec($_, 6, 4) = 1 == 16777216 00000000000000000000000010000000 vec($_, 7, 4) = 1 == 268435456 00000000000000000000000000001000 vec($_, 0, 4) = 2 == 2 01000000000000000000000000000000 vec($_, 1, 4) = 2 == 32 00000100000000000000000000000000 vec($_, 2, 4) = 2 == 512 00000000010000000000000000000000 vec($_, 3, 4) = 2 == 8192 00000000000001000000000000000000 vec($_, 4, 4) = 2 == 131072 00000000000000000100000000000000 vec($_, 5, 4) = 2 == 2097152 00000000000000000000010000000000 vec($_, 6, 4) = 2 == 33554432 00000000000000000000000001000000 vec($_, 7, 4) = 2 == 536870912 00000000000000000000000000000100 vec($_, 0, 4) = 4 == 4 00100000000000000000000000000000 vec($_, 1, 4) = 4 == 64 00000010000000000000000000000000 vec($_, 2, 4) = 4 == 1024 00000000001000000000000000000000 vec($_, 3, 4) = 4 == 16384 00000000000000100000000000000000 vec($_, 4, 4) = 4 == 262144 00000000000000000010000000000000 vec($_, 5, 4) = 4 == 4194304 00000000000000000000001000000000 vec($_, 6, 4) = 4 == 67108864 00000000000000000000000000100000 vec($_, 7, 4) = 4 == 1073741824 00000000000000000000000000000010 vec($_, 0, 4) = 8 == 8 00010000000000000000000000000000 vec($_, 1, 4) = 8 == 128 00000001000000000000000000000000 vec($_, 2, 4) = 8 == 2048 00000000000100000000000000000000 vec($_, 3, 4) = 8 == 32768 00000000000000010000000000000000 vec($_, 4, 4) = 8 == 524288 00000000000000000001000000000000 vec($_, 5, 4) = 8 == 8388608 00000000000000000000000100000000 vec($_, 6, 4) = 8 == 134217728 00000000000000000000000000010000 vec($_, 7, 4) = 8 == 2147483648 00000000000000000000000000000001 vec($_, 0, 8) = 1 == 1 10000000000000000000000000000000 vec($_, 1, 8) = 1 == 256 00000000100000000000000000000000 vec($_, 2, 8) = 1 == 65536 00000000000000001000000000000000 vec($_, 3, 8) = 1 == 16777216 00000000000000000000000010000000 vec($_, 0, 8) = 2 == 2 01000000000000000000000000000000 vec($_, 1, 8) = 2 == 512 00000000010000000000000000000000 vec($_, 2, 8) = 2 == 131072 00000000000000000100000000000000 vec($_, 3, 8) = 2 == 33554432 00000000000000000000000001000000 vec($_, 0, 8) = 4 == 4 00100000000000000000000000000000 vec($_, 1, 8) = 4 == 1024 00000000001000000000000000000000 vec($_, 2, 8) = 4 == 262144 00000000000000000010000000000000 vec($_, 3, 8) = 4 == 67108864 00000000000000000000000000100000 vec($_, 0, 8) = 8 == 8 00010000000000000000000000000000 vec($_, 1, 8) = 8 == 2048 00000000000100000000000000000000 vec($_, 2, 8) = 8 == 524288 00000000000000000001000000000000 vec($_, 3, 8) = 8 == 134217728 00000000000000000000000000010000 vec($_, 0, 8) = 16 == 16 00001000000000000000000000000000 vec($_, 1, 8) = 16 == 4096 00000000000010000000000000000000 vec($_, 2, 8) = 16 == 1048576 00000000000000000000100000000000 vec($_, 3, 8) = 16 == 268435456 00000000000000000000000000001000 vec($_, 0, 8) = 32 == 32 00000100000000000000000000000000 vec($_, 1, 8) = 32 == 8192 00000000000001000000000000000000 vec($_, 2, 8) = 32 == 2097152 00000000000000000000010000000000 vec($_, 3, 8) = 32 == 536870912 00000000000000000000000000000100 vec($_, 0, 8) = 64 == 64 00000010000000000000000000000000 vec($_, 1, 8) = 64 == 16384 00000000000000100000000000000000 vec($_, 2, 8) = 64 == 4194304 00000000000000000000001000000000 vec($_, 3, 8) = 64 == 1073741824 00000000000000000000000000000010 vec($_, 0, 8) = 128 == 128 00000001000000000000000000000000 vec($_, 1, 8) = 128 == 32768 00000000000000010000000000000000 vec($_, 2, 8) = 128 == 8388608 00000000000000000000000100000000 vec($_, 3, 8) = 128 == 2147483648 00000000000000000000000000000001
use POSIX ":sys_wait_h"; #... do { $kid = waitpid(-1,&WNOHANG); } until $kid == -1;
alors vous pouvez réaliser une attente non bloquante sur plusieurs process. Les attentes non bloquantes sont disponibles sur les machines qui connaissent l'un des deux appels système waitpid(2) ou wait4(2). Par contre, l'attente d'un process particulier avec FLAGS à 0 est implémenté partout. (Perl émule l'appel système en se souvenant des valeurs du statut des process qui ont terminé mais qui n'ont pas encore été collectées par le script Perl.)
Remarquez que sur certains systèmes, une valeur de retour "-1" peut signifier que les process fils ont été automatiquement collectés. Voir perlipc pour les détails et d'autres exemples.
return unless defined wantarray; # inutile d'en faire plus my @a = complex_calculation(); return wantarray ? @a : "@a";
Cette fonction aurait dû s'appeler wantlist().
Si LISTE est vide et si $@ contient encore une valeur (provenant par exemple d'un eval précédent) alors cette valeur est utilisée après y avoir ajouté "\t...caught". C'est pratique pour s'approcher d'un comportement presque similaire à "die()".
Si $@ est vide alors la chaîne "Warning: Something's wrong" (N.d.t : "Attention: quelque chose va mal") est utilisée.
Aucune message n'est affiché si une subroutine est attachée à $SIG{__WARN__}. C'est de la responsabilité de cette subroutine de gérer le message comme elle le veut (en le convertissant en un "die()" par exemple). La plupart des subroutine du genre devraient s'arranger pour afficher réellement les messages qu'elles ne sont pas prêtes à recevoir en appelant à nouveau "warn()". Remarquez que cela fonctionne sans produire une boucle sans fin puisque les subroutines attachées à "__WARN__" ne sont pas appelés à partir d'une subroutine attachée.
Ce comportement est complètement différent de celui des subroutine attachées à $SIG{__DIE__} (qui ne peuvent pas supprimer le texte d'erreur mais seulement le remplacer en appelant à nouveau "die()").
L'utilisation d'une subroutine attachée à "__WARN__" fournit un moyen puissant pour supprimer tous les messages d'avertissement (même ceux considérés comme obligatoires). Un exemple :
# supprime *tous* les messages d'avertissement lors de la compilation BEGIN { $SIG{'__WARN__'} = sub { warn $_[0] if $DOWARN } } my $foo = 10; my $foo = 20; # pas d'avertissement pour la duplication de # $foo... mais c'est ce qu'on voulait ! # pas de messages d'avertissement avant ici $DOWARN = 1;
# messages d'avertissement à partir d'ici warn "\$foo is alive and $foo!"; # devrait apparaître
Voir perlvar pour plus de détails sur la modification de entrées de %SIG et pour plus d'exemples. Voir le module Carp pour d'autres sortes d'avertissement utilisant les fonctions carp() et cluck().
Le calcul de l'en-tête est fait automatiquement : si il n'y a pas assez de place sur la page courante pour l'enregistrement formaté, on passe à la page suivante en affichant un format d'en-tête spécial puis on y écrit l'enregistrement formaté. Par défaut, le nom du format d'en-tête spécial est le nom du descripteur auquel on ajoute ``_TOP'' mais il peut être dynamiquement modifié en affectant le nom du format voulu à la variable $^ lorsque le descripteur est sélectionné (par select()). Le nombre de lignes restant dans la page courante est donné par la variable "$-" qui peut être mise à 0 pour forcer le passage à la page suivante.
Si DESCRIPTEUR n'est pas spécifié, le sortie se fait sur le canal de sortie courant qui, au début, est STDOUT mais qui peut être changé par l'opérateur "select()". Si le DESCRIPTEUR est une expression EXPR alors l'expression est évaluée et la chaîne résultante est utilisé comme nom du descripteur à utiliser. Pour en savoir plus sur les formats, voir perlform.
Notez que write n'est PAS le contraire de "read()". Malheureusement.
Mise à jour en 5.6.0 : Paul Gaborit <paul.gaborit@enstimac.fr>.