.\" Automatically generated by Pod::Man 2.09 (Pod::Simple 3.04) .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "PERLREFTUT 1" .TH PERLREFTUT 1 "2006-03-07" "DocFr" "User Contributed Perl Documentation" .SH "NAME/NOM" .IX Header "NAME/NOM" perlreftut \- Le tre\*`s court tutoriel de Mark sur les re\*'fe\*'rences .SH "DESCRIPTION" .IX Header "DESCRIPTION" Une des caracte\*'ristiques nouvelles les plus importantes de Perl 5 a e\*'te\*' la capacite\*' de ge\*'rer des structures de donne\*'es complique\*'es comme les tableaux multidimensionnels et les tables de hachage imbrique\*'es. Pour les rendre possibles, Perl 5 a introduit un me\*'canisme appele\*' \*(L"re\*'fe\*'rences\*(R" ; l'utilisation de celles-ci est le moyen de travailler avec des donne\*'es complexes structure\*'es en Perl. Malheureusement, cela fait une grande quantite\*' de syntaxe nouvelle a\*` apprendre, et la page de manuel est parfois difficile a\*` suivre. Cette dernie\*`re est tre\*`s comple\*`te, et cela peut e\*^tre un proble\*`me parce qu'il est difficile d'en tirer ce qui est important et ce qui ne l'est pas. .PP Heureusement, vous avez seulement besoin de savoir 10% de ce qui est dans la page de manuel principale pour tirer 90% de son be\*'ne\*'fice. Cette page espe\*`re vous montrer ces 10%. .SH "Qui a besoin de structures de donne\*'es complique\*'es ?" .IX Header "Qui a besoin de structures de donne'es complique'es ?" Un proble\*`me qui revenait souvent avec Perl 4 e\*'tait celui de la repre\*'sentation d'une table de hachage dont les valeurs sont des listes. Perl 4 avait les tables de hachage, bien su\*^r, mais les valeurs devaient e\*^tre des scalaires ; elles ne pouvaient e\*^tre des listes. .PP Pourquoi voudrait-on utiliser une table de hachage contenant des listes ? Prenons un exemple simple. Vous avez un fichier contenant des noms de villes et de pays, comme ceci: .PP .Vb 6 \& Chicago, USA \& Frankfort, Allemagne \& Berlin, Allemagne \& Washington, USA \& Helsinki, Finlande \& New York, USA .Ve .PP et vous voulez produire une sortie comme cela, avec chaque pays mentionne\*' une seule fois, suivi d'une liste des villes de ce pays\ : .PP .Vb 3 \& Finlande: Helsinki. \& Allemagne: Berlin, Frankfort. \& USA: Chicago, New York, Washington. .Ve .PP La fac\*,on naturelle de faire ceci est de construire une table de hachage dont les cle\*'s sont les noms des pays. A chaque pays cle\*' on associe une liste des villes de ce pays. Chaque fois qu'on lit une ligne en entre\*'e, on la se\*'pare en un pays et une ville, on recherche la liste de villes de\*'ja\*` connues pour ce pays, et on y ajoute la nouvelle ville. Quand on a fini de lire les donne\*'es en entre\*'e, on parcourt la table de hachage, en triant chaque liste de villes avant de l'afficher. .PP Si les valeurs des tables de hachage ne peuvent e\*^tre des listes, c'est perdu. En Perl 4, c'est le cas ; ces valeurs ne peuvent e\*^tre que de chai\*^nes de caracte\*`res. C'est donc perdu. Nous devrions probablement essayer de combiner toutes les villes dans une seule grande chai\*^ne de caracte\*`res, et au moment d'e\*'crire la sortie, couper cette chai\*^ne pour en faire une liste, la trier, et la reconvertir en chai\*^ne de caracte\*`res. C'est complique\*', et il est facile de faire des erreurs dans le processus. C'est surtout frustrant, parce que Perl a de\*'ja\*` de tre\*`s belles listes qui re\*'soudraient le proble\*`me, si seulement nous pouvions les utiliser. .SH "La solution" .IX Header "La solution" Avant me\*^me que Perl 5 ne pointa\*^t le bout de son nez, nous e\*'tions donc coince\*'s avec ce fait de conception\ : les valeurs de tables de hachage doivent e\*^tre des scalaires. Les re\*'fe\*'rences sont la solution a\*` ce proble\*`me. .PP Une re\*'fe\*'rence est une valeur scalaire qui \fIfait re\*'fe\*'rence a\*`\fR un tableau entier ou a\*` une table de hachage entie\*`re (ou a\*` a\*` peu pre\*`s n'importe quoi d'autre). Les noms sont une forme de re\*'fe\*'rence dont vous e\*^tes de\*'ja\*` familier. Pensez au Pre\*'sident des E\*'tats\-Unis D'Ame\*'rique: ce n'est qu'un tas de\*'sordonne\*' et inutilisable de sang et d'os. Mais pour parler de lui, ou le repre\*'senter dans un programme d'ordinateur, tout ce dont vous avez besoin est le sympathique et maniable scalaire \&\*(L"George Bush\*(R". .PP Les re\*'fe\*'rences en Perl sont comme des noms pour les tableaux et les tables de hachage. Ce sont des noms prive\*'s et internes de Perl, vous pouvez donc e\*^tre su\*^r qu'ils ne sont pas ambigus. Au contraire de \&\*(L"George Bush\*(R", une re\*'fe\*'rence pointe vers une seule chose, et il est toujours possible de savoir vers quoi. Si vous avez une re\*'fe\*'rence a\*` un tableau, vous pouvez acce\*'der au tableau complet qui est derrie\*`re. Si vous avez une re\*'fe\*'rence a\*` une table de hachage, vous pouvez acce\*'der a\*` la table entie\*`re. Mais la re\*'fe\*'rence reste un scalaire, compact et facile a\*` manipuler. .PP Vous ne pouvez pas construire une table de hachage dont les valeurs sont des tableaux\ : les valeurs des tables de hachage ne peuvent e\*^tre que des scalaires. Nous y somme condamne\*'s. Mais une seule re\*'fe\*'rence peut pointer vers un tableau entier, et les re\*'fe\*'rences sont des scalaires, donc vous pouvez avoir une table de hachage de re\*'fe\*'rences a\*` des tableaux, et elle agira presque comme une table de hachage de tableaux, et elle pourra servir juste comme une table de hachage de tableaux. .PP Nous reviendrons a\*` notre proble\*`me de villes et de pays plus tard, apre\*`s avoir introduit un peu de syntaxe pour ge\*'rer les re\*'fe\*'rences. .SH "Syntaxe" .IX Header "Syntaxe" Il n'y a que deux fac\*,ons de construire une re\*'fe\*'rence, et deux fac\*,ons de l'utiliser une fois qu'on l'a. .Sh "Construire des re\*'fe\*'rences" .IX Subsection "Construire des re'fe'rences" \fI\f(BIRe\*`gle de construction 1\fI\fR .IX Subsection "Re`gle de construction 1" .PP Si vous mettez un \f(CW\*(C`\e\*(C'\fR devant une variable, vous obtenez une re\*'fe\*'rence a\*` cette variable. .PP .Vb 6 \& $tref = \e@tableau; # $tref contient maintenant une re\*'fe\*'rence \& # a\*` @tableau \& $href = \e%hachage; # $href contient maintenant une re\*'fe\*'rence \& # a\*` %hachage \& $sref = \e$scalaire; # $sref contient maintenant une re\*'fe\*'rence \& # a\*` $scalaire .Ve .PP Une fois que la re\*'fe\*'rence est stocke\*'e dans une variable comme \f(CW$tref\fR ou \&\f(CW$href\fR, vous pouvez la copier ou la stocker ailleurs comme n'importe quelle autre valeur scalaire\ : .PP .Vb 6 \& $xy = $tref; # $xy contient maintenant une re\*'fe\*'rence \& # a\*` @tableau \& $p[3] = $href; # $p[3] contient maintenant une re\*'fe\*'rence \& # a\*` %hachage \& $z = $p[3]; # $z contient maintenant une re\*'fe\*'rence \& # a\*` %hachage .Ve .PP Ces exemples montrent comment cre\*'er des re\*'fe\*'rences a\*` des variables avec un nom. Parfois, on veut utiliser un tableau ou une table de hachage qui n'a pas de nom. C'est un peu comme pour les chai\*^nes de caracte\*`res et les nombres\ : on veut e\*^tre capable d'utiliser la chai\*^ne \&\f(CW"\en"\fR ou le nombre 80 sans avoir a\*` les stocker dans une variable nomme\*'e d'abord. .PP \fI\f(BIRe\*`gle de construction 2\fI\fR .IX Subsection "Re`gle de construction 2" .PP \&\f(CW\*(C`[ ELEMENTS ]\*(C'\fR cre\*'e un nouveau tableau anonyme, et renvoie une re\*'fe\*'rence a\*` ce tableau. \f(CW\*(C`{ ELEMENTS }\*(C'\fR cre\*'e une nouvelle table de hachage anonyme et renvoie une re\*'fe\*'rence a\*` cette table. .PP .Vb 2 \& $tref = [ 1, "toto", undef, 13 ]; \& # $tref contient maintenant une re\*'fe\*'rence a\*` un tableau \& \& $href = { AVR => 4, AOU => 8 }; \& # $href contient maintenant une re\*'fe\*'rence a\*` une table de hachage .Ve .PP Les re\*'fe\*'rences obtenues gra\*^ce a\*` la re\*`gle 2 sont de la me\*^me espe\*`ce que celles obtenues par la re\*`gle 1\ : .PP .Vb 2 \& # Ceci : \& $tref = [ 1, 2, 3 ]; \& \& # Fait la me\*^me chose que cela : \& @tableau = (1, 2, 3); \& $tref = \e@tableau; .Ve .PP La premie\*`re ligne est une abre\*'viation des deux lignes suivantes, a\*` ceci pre\*`s qu'elle ne cre\*'e pas la variable tableau superflue \&\f(CW@tableau\fR. .PP Si vous e\*'crivez \f(CW\*(C`[]\*(C'\fR, vous obtenez une re\*'fe\*'rence a\*` un nouveau tableau anonyme vide. Si vous e\*'crivez \f(CW\*(C`{}\*(C'\fR, vous obtenez une re\*'fe\*'rence a\*` un nouvelle table de hachage anonyme vide. .Sh "Utiliser les re\*'fe\*'rences" .IX Subsection "Utiliser les re'fe'rences" Une fois qu'on a une re\*'fe\*'rence, que peut-on en faire? C'est une valeur scalaire, et nous avons vu que nous pouvons la stocker et la re\*'cupe\*'rer ensuite comme n'importe quel autre scalaire. Il y juste deux fac\*,ons de plus de l'utiliser\ : .PP \fI\f(BIRe\*`gle d'utilisation 1\fI\fR .IX Subsection "Re`gle d'utilisation 1" .PP A\*` la place du nom d'un tableau, vous pouvez toujours utiliser une re\*'fe\*'rence a\*` un tableau, tout simplement en la plac\*,ant entre accolades. Par exemple, \f(CW\*(C`@{$tref}\*(C'\fR la place de \f(CW@tableau\fR. .PP En voici quelques exemples\ : .PP Tableaux\ : .PP .Vb 4 \& @t @{$tref} Un tableau \& reverse @t reverse @{$tref} Inverser un tableau \& $t[3] ${$tref}[3] Un e\*'le\*'ment du tableau \& $t[3] = 17; ${$tref}[3] = 17 Affecter un e\*'le\*'ment .Ve .PP Sur chaque ligne, les deux expressions font la me\*^me chose. Celles de gauche travaillent sur le tableau \f(CW@t\fR, et celles de droite travaillent sur le tableau vers lequel pointe \f(CW$tref\fR ; mais une fois qu'elle ont acce\*'de\*' au tableau sur lequel elles ope\*`rent, elles leur font exactement la me\*^me chose. .PP On utilise une re\*'fe\*'rence a\*` une table de hachage \f(CW\*(C`exactement\*(C'\fR de la me\*^me fac\*,on\ : .PP .Vb 5 \& %h %{$href} Une table de hachage \& keys %h keys %{$href} Obtenir les cle\*'s de la \& table \& $h{'bleu'} ${$href}{'bleu'} Un e\*'le\*'ment de la table \& $h{'bleu'} = 17 ${$href}{'bleu'} = 17 Affecter un e\*'le\*'ment .Ve .PP Quelque soit ce que vous voulez faire avec une re\*'fe\*'rence, vous pouvez y arriver en appliquant la \fBRe\*`gle d'utilisation 1\fR. Vous commencez par e\*'crire votre code Perl en utilisant un vrai tableau ou une vraie table de hachage puis vous remplacez le nom du tableau ou de la table par \f(CW\*(C`{$reference}\*(C'\fR. .PP \&\*(L"Comment faire une boucle sur un tableau pour lequel je ne posse\*`de qu'une re\*'fe\*'rence\ ?\*(R" Pour faire une boucle sur un tableau \&\*(L"normal\*(R" vous auriez e\*'crit\ : .PP .Vb 3 \& for my $element (@tableau) { \& ... \& } .Ve .PP Remplac\*,ons donc le nom du tableau (\f(CW\*(C`tableau\*(C'\fR) par la re\*'fe\*'rence\ : .PP .Vb 3 \& for my $element (@{$tref}) { \& ... \& } .Ve .PP \&\*(L"Comment afficher le contenu d'une table de hachage dont je posse\*`de une re\*'fe\*'rence\ ?\*(R" Tout d'abord, e\*'crivons le code pour afficher le contenu d'une table de hachage\ : .PP .Vb 3 \& for my $cle (keys %hachage) { \& print "$cle => $hachage{$cle}\en"; \& } .Ve .PP Puis remplac\*,ons le nom de la table par la re\*'fe\*'rence\ : .PP .Vb 3 \& for my $cle (keys %${href}) { \& print "$cle => $${href}{$cle}\en"; \& } .Ve .PP \fI\f(BIRe\*`gle d'utilisation 2\fI\fR .IX Subsection "Re`gle d'utilisation 2" .PP La \fBRe\*`gle d'utilisation 1\fR est la seule re\*'ellement indispensable puisqu'elle vous permet de faire tout ce que vous voulez avec des re\*'fe\*'rences. Mais le chose la plus courante que l'on fait avec un tableau ou une table de hachage est d'acce\*'der a\*` une valeur et la notation induite par la \fBRe\*`gle d'utilisation 1\fR est lourde. Il existe donc une notation raccourcie. .PP \&\f(CW\*(C`${$tref}[3]\*(C'\fR est trop dur a\*` lire, vous pouvez donc e\*'crire \f(CW\*(C`$tref\->[3]\*(C'\fR a\*` la place. .PP \&\f(CW\*(C`${$href}{bleu}\*(C'\fR est trop dur a\*` lire, vous pouvez donc e\*'crire \&\f(CW\*(C`$href\->{bleu}\*(C'\fR a\*` la place. .PP Si \f(CW$tref\fR est une re\*'fe\*'rence a\*` un tableau, alors \f(CW\*(C`$tref\->[3]\*(C'\fR est le quatrie\*`me e\*'le\*'ment du tableau. Ne me\*'langez pas c\*,a avec \f(CW$tref[3]\fR, qui est le quatrie\*`me e\*'le\*'ment d'un tout autre tableau, trompeusement nomme\*' \&\f(CW@tref\fR. \f(CW$tref\fR et \f(CW@tref\fR ne sont pas relie\*'s, pas plus que \f(CW$truc\fR et \&\f(CW@truc\fR. .PP De la me\*^me fac\*,on, \f(CW\*(C`$href\->{'bleu'}\*(C'\fR est une partie de la table de hachage vers laquelle pointe \f(CW$href\fR, et qui ne porte peut\-e\*^tre pas de nom. \f(CW$href{'bleu'}\fR est une partie de la table de hachage trompeusement nomme\*'e \f(CW%href\fR. Il est facile d'oublier le \f(CW\*(C`\->\*(C'\fR, et si cela vous arrive vous obtiendrez des re\*'sultats e\*'tranges comme votre programme utilisera des tableaux et des tables de hachage issus de tableaux et de tables de hachages qui n'e\*'taient pas ceux que vous aviez l'intention d'utiliser. .SH "Un exemple" .IX Header "Un exemple" Voyons un rapide exemple de l'utilite\*' de tout ceci. .PP D'abord, souvenez-vous que \f(CW\*(C`[1, 2, 3]\*(C'\fR construit un tableau anonyme contenant \f(CW\*(C`(1, 2, 3)\*(C'\fR, et vous renvoie une re\*'fe\*'rence a\*` ce tableau. .PP Maintenant, conside\*'rez .PP .Vb 4 \& @t = ( [1, 2, 3], \& [4, 5, 6], \& [7, 8, 9] \& ); .Ve .PP \&\f(CW@t\fR est un tableau a\*` trois e\*'le\*'ments, et chacun d'entre eux est une re\*'fe\*'rence a\*` un autre tableau. .PP \&\f(CW$t[1]\fR est l'une de ces re\*'fe\*'rences. Elle pointe vers un tableau, celui contenant \f(CW\*(C`(4, 5, 6)\*(C'\fR, et puisque c'est une re\*'fe\*'rence a\*` un tableau, la \f(CW\*(C`Re\*`gle d'utilisation 2\*(C'\fR dit que nous pouvons e\*'crire \&\f(CW$t[1]\->[2]\fR pour acce\*'der au troisie\*`me e\*'le\*'ment du tableau. \&\f(CW$t[1]\->[2]\fR vaut 6. De la me\*^me fac\*,on, \f(CW$t[0]\->[1]\fR vaut 2. Nous avons ce qui ressemble a\*` un tableau de dimensions deux ; vous pouvez e\*'crire \f(CW$t[LIGNE]\->[COLONNE]\fR pour obtenir ou modifier l'e\*'le\*'ment se trouvant a\*` une ligne et une colonne donne\*'es du tableau. .PP Notre notation est toujours quelque peu maladroite, voici donc un raccourci de plus\ : .SH "Re\*`gle de la fle\*`che" .IX Header "Re`gle de la fle`che" Entre deux \fBindices\fR, la fle\*`che et facultative. .PP A la place de \f(CW$t[1]\->[2]\fR, nous pouvons e\*'crire \f(CW$t[1][2]\fR ; cela veut dire la me\*^me chose. A la place de \f(CW\*(C`$t[0]\->[1] = 23\*(C'\fR, nous pouvons e\*'crire \f(CW\*(C`$t[0][1] = 23\*(C'\fR ; cela veut dire la me\*^me chose. .PP Maintenant on dirait vraiment un tableau a\*` deux dimensions ! .PP Vous pouvez voir pourquoi les fle\*`ches sont importantes. Sans elles, nous devrions e\*'crire \f(CW\*(C`${$t[1]}[2]\*(C'\fR a\*` la place de \f(CW$t[1][2]\fR. Pour les tableaux a\*` trois dimensions, elles nous permettent d'e\*'crire \&\f(CW$x[2][3][5]\fR a\*` la place de l'illisible \f(CW\*(C`${${$x[2]}[3]}[5]\*(C'\fR. .SH "Solution" .IX Header "Solution" Voici maintenant la re\*'ponse au proble\*`me que j'ai pose\*' plus haut, qui consistait a\*` reformater un fichier de villes et de pays. .PP .Vb 1 \& 1 my %table; \& \& 2 while (<>) { \& 3 chomp; \& 4 my ($ville, $pays) = split /, /; \& 5 $table{$pays} = [] unless exists $table{$pays}; \& 6 push @{$table{$pays}}, $ville; \& 7 } \& \& 8 foreach $pays (sort keys %table) { \& 9 print "$pays: "; \& 10 my @villes = @{$table{$pays}}; \& 11 print join ', ', sort @villes; \& 12 print ".\en"; \& 13 } .Ve .PP Ce programme est constitue\*' de deux parties\ : les lignes 2 a\*` 7 lisent les donne\*'es et construisent une structure de donne\*'es puis les lignes 8 a\*` 13 analysent les donne\*'es et impriment un rapport. Nous allons obtenir une table de hachage dont les cle\*'s sont les noms de pays et dont les valeurs sont des re\*'fe\*'rences vers des tableaux de noms de villes. La structure de donne\*'es ressemblera a\*` cela\ : .PP .Vb 10 \& %table \& +\-\-\-\-\-\-\-+\-\-\-+ \& | | | +\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+ \& |Germany| *\-\-\-\->| Frankfurt | Berlin | \& | | | +\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-+ \& +\-\-\-\-\-\-\-+\-\-\-+ \& | | | +\-\-\-\-\-\-\-\-\-\-+ \& |Finland| *\-\-\-\->| Helsinki | \& | | | +\-\-\-\-\-\-\-\-\-\-+ \& +\-\-\-\-\-\-\-+\-\-\-+ \& | | | +\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+ \& | USA | *\-\-\-\->| Chicago | Washington | New York | \& | | | +\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-\-\-+\-\-\-\-\-\-\-\-\-\-+ \& +\-\-\-\-\-\-\-+\-\-\-+ .Ve .PP Commenc\*,ons par de\*'tailler la seconde partie du code. Supposons donc que nous avons de\*'ja\*` cette structure. Comment l'afficher ? .PP .Vb 6 \& 8 foreach $pays (sort keys %table) { \& 9 print "$pays: "; \& 10 my @villes = @{$table{$pays}}; \& 11 print join ', ', sort @villes; \& 12 print ".\en"; \& 13 } .Ve .PP \&\f(CW%table\fR est une table de hachage ordinaire dont on extrait les cle\*'s en les triant afin de les parcourir. La seule utilisation d'une re\*'fe\*'rence est en ligne 10. \f(CW$table{$pays}\fR acce\*`de, via la cle\*' \f(CW$pays\fR, a\*` une valeur qui est une re\*'fe\*'rence a\*` un tableau de villes de ce pays. La \fBRe\*`gle d'utilisation 1\fR indique que nous pouvons obtenir ce tableau en e\*'crivant \f(CW\*(C`@{$table{$pays}}\*(C'\fR. La ligne 10 est donc comme\ : .PP .Vb 1 \& @villes = @tableau; .Ve .PP sauf que le nom \f(CW\*(C`tableau\*(C'\fR a e\*'te\*' remplace\*' par la re\*'fe\*'rence \&\f(CW\*(C`{$table{$pays}}\*(C'\fR. Le \f(CW\*(C`@\*(C'\fR indique a\*` Perl qu'on veut tout le tableau. Une fois le tableau des villes re\*'cupe\*'re\*', on trie et on concate\*`ne ses valeurs pour finalement les afficher comme d'habitude. .PP Les ligne 2 a\*` 7 fabriquent la structure de donne\*'es. Les voici a\*` nouveau\ : .PP .Vb 6 \& 2 while (<>) { \& 3 chomp; \& 4 my ($ville, $pays) = split /, /; \& 5 $table{$pays} = [] unless exists $table{$pays}; \& 6 push @{$table{$pays}}, $ville; \& 7 } .Ve .PP Les lignes 2 a\*` 4 re\*'cupe\*`rent les noms d'une ville et d'un pays. La ligne 5 regarde si ce pays existe de\*'ja\*` en tant que cle\*' de la table de hachage. Si elle n'existe pas, le programme utilise la notation \f(CW\*(C`[]\*(C'\fR (\fBRe\*`gle de construction 2\fR) pour cre\*'er une re\*'fe\*'rence a\*` un nouveau tableau anonyme vide pre\*^t a\*` accueillir des noms de villes. Cette re\*'fe\*'rence est associe\*'e a\*` la cle\*' approprie\*'e dans la table de hachage. .PP La ligne 6 ajoute le nom de la ville dans le tableau approprie\*'. \f(CW$table{$pays}\fR contient une re\*'fe\*'rence au tableau de noms de villes du pays concerne\*'. La ligne 6 est exactement comme\ : .PP .Vb 1 \& push @tableau, $ville; .Ve .PP sauf que le nom \f(CW\*(C`tableau\*(C'\fR a e\*'te\*' remplace\*' par la re\*'fe\*'rence \&\f(CW\*(C`{$table{$pays}}\*(C'\fR. Le \f(CW\*(C`push\*(C'\fR ajoute un nom de ville a\*` la fin du tableau re\*'fe\*'rence\*'. .PP Il y a un de\*'tail que j'ai omis. La ligne 5 est en fait inutile et nous pourrions e\*'crire\ : .PP .Vb 6 \& 2 while (<>) { \& 3 chomp; \& 4 my ($ville, $pays) = split /, /; \& 5 #### $table{$pays} = [] unless exists $table{$pays}; \& 6 push @{$table{$pays}}, $ville; \& 7 } .Ve .PP Si, dans \f(CW%table\fR, il y a de\*'ja\*` une valeur associe\*'e a\*` la cle\*' \f(CW$pays\fR, cela ne change rien. La ligne 6 retrouve la valeur de \f(CW$table{$pays}\fR qui est une re\*'fe\*'rence a\*` un tableau et ajoute la ville dans ce tableau. Mais qeu se passe-t-il si \f(CW$pays\fR contient un cle\*', disons \&\f(CW\*(C`Gre\*`ce\*(C'\fR, qui n'existe pas encore dans \f(CW%table\fR ? .PP Comme c'est du Perl, il se passe exactement ce qu'il faut. Perl voit que nous voulons ajouter \f(CW\*(C`Athe\*`nes\*(C'\fR a\*` un tableau qui n'existe pas alors il cre\*'e un nouveau tableau vide pour nous, l'inscrit dans \&\f(CW%table\fR et y ajoute \f(CW\*(C`Athe\*`nes\*(C'\fR. Ceci s'appelle \*(L"l'autovivification\*(R" \&\*(-- donner vie a\*` quelque chose automagiquement. Perl voit que la cle\*' n'existe pas dans la table de hachage et donc il cre\*'e cette nouvelle cle\*' automatiquement. Perl voit ensuite que vous voulez utilisez cette valeur comme une re\*'fe\*'rence a\*` un tableau alors il cre\*'e un nouveau tableau vide et stocke automatiquement sa re\*'fe\*'rence dans la table de hachage. Ensuite, comme d'habitude, Perl augmente la taille du tableau afin d'y ajouter le nouveau nom. .SH "Le reste" .IX Header "Le reste" J'ai promis de vous donner acce\*`s a\*` 90% du be\*'ne\*'fice avec 10% des de\*'tails, et cela implique que j'ai laisse\*' de co\*^te\*' 90% des de\*'tails. Maintenant que vous avez une vue d'ensemble des e\*'le\*'ments importants, il devrait vous e\*^tre plus facile de lire la page de manuel perlref, qui passe en revue 100% des de\*'tails. .PP Quelques unes de grande lignes de perlref\ : .IP "\(bu" 4 Vous pouvez cre\*'er des re\*'fe\*'rences a\*` n'importe quoi, ce qui inclut des scalaires, des fonctions, et d'autres re\*'fe\*'rences. .IP "\(bu" 4 Dans la \fBRe\*`gle d'utilisation 1\fR, vous pouvez omettre les accolades quand ce qui est a\*` l'inte\*'rieur est une variable scalaire atomique comme \f(CW$tref\fR. Par exemple, \f(CW@$tref\fR est identique a\*` \f(CW\*(C`@{$tref}\*(C'\fR, et \&\f(CW$$tref[1]\fR est identique a\*` \f(CW\*(C`${$tref}[1]\*(C'\fR. Si vous de\*'butez, vous pre\*'fe\*'rerez su\*^rement adopter l'habitude de toujours e\*'crire les accolades. .IP "\(bu" 4 Le code suivant ne recopie pas le tableau re\*'fe\*'rence\*' par \&\f(CW$tref1\fR\ : .Sp .Vb 1 \& $tref2 = $tref1; .Ve .Sp Vous obtenez en fait deux re\*'fe\*'rences au me\*^me tableau. Si vous modifiez \&\f(CW\*(C`$tref1\->[23]\*(C'\fR et que vous regardez la valeur de \f(CW\*(C`$tref2\->[23]\*(C'\fR vous verrez la modification. .Sp Pour copier le contenu du tableau, e\*'crivez\ : .Sp .Vb 1 \& $tref2 = [@{$tref1}]; .Ve .Sp On utilise la notation \f(CW\*(C`[...]\*(C'\fR pour cre\*'er un nouveau tableau anonyme et affecter sa re\*'fe\*'rence a\*` \f(CW$tref2\fR. Le contenu du nouveau tableau est initialise\*' avec les valeurs contenues dans le tableau re\*'fe\*'rence\*' par \f(CW$tref1\fR. .Sp De manie\*`re similaire, pour copier un table de hachage anonyme, on e\*'crit\ : .Sp .Vb 1 \& $href2 = {%{$href1}}; .Ve .IP "\(bu" 4 Pour voir si une variable contient une re\*'fe\*'rence, utilisez la fonction \&\*(L"ref\*(R". Elle renvoie vrai si son argument est une re\*'fe\*'rence. En fait, c'est encore mieux que c\*,a\ : elle renvoie \s-1HASH\s0 pour les re\*'fe\*'rences a\*` une table de hachage et \s-1ARRAY\s0 pour les re\*'fe\*'rences a\*` un tableau. .IP "\(bu" 4 Si vous essayez d'utiliser une re\*'fe\*'rence comme une chai\*^ne de caracte\*`res, vous obtenez quelque-chose comme .Sp .Vb 1 \& ARRAY(0x80f5dec) ou HASH(0x826afc0) .Ve .Sp Si jamais vous voyez une chai\*^ne de caracte\*`res qui ressemble a\*` c\*,a, vous saurez que vous avez imprime\*' une re\*'fe\*'rence par erreur. .Sp Un effet de bord de cette repre\*'sentation est que vous pouvez utiliser \&\f(CW\*(C`eq\*(C'\fR pour savoir si deux re\*'fe\*'rences pointent vers la me\*^me chose. (Mais d'ordinaire vous devriez pluto\*^t utiliser \f(CW\*(C`==\*(C'\fR parce que c'est beaucoup plus rapide.) .IP "\(bu" 4 Vous pouvez utiliser une chai\*^ne de caracte\*`res comme si c'e\*'tait une re\*'fe\*'rence. Si vous utilisez la chai\*^ne \f(CW"foo"\fR comme une re\*'fe\*'rence a\*` un tableau, elle est prise comme une re\*'fe\*'rence au tableau \f(CW@foo\fR. On appelle cela une \f(CW\*(C`re\*'fe\*'rence symbolique\*(C'\fR. Le pragma \f(CW\*(C`use strict \&'refs'\*(C'\fR (NdT\ : et me\*^me \f(CW\*(C`use strict\*(C'\fR) de\*'sactive cette fonctionnalite\*' qui, lorsqu'elle est utilise\*'e accidentellement, peut provoquer plein de bugs. .PP Vous pourriez pre\*'fe\*'rer continuer avec perllol au lieu de perlref ; il y est traite\*' des listes de listes et des tableaux multidimensionnels en de\*'tail. Apre\*`s cela, vous devriez avancer vers perldsc ; c'est un livre de recettes pour les structures de donne\*'es (\fIData Structure Cookbook\fR) qui montre les recettes pour utiliser et imprimer les tableaux de tables de hachage, les tables de hachage de tableaux, et les autres sortes de donne\*'es. .SH "Re\*'sume\*'" .IX Header "Re'sume'" Tout le monde a besoin de structures de donne\*'es complexes, et les re\*'fe\*'rences sont le moyen d'y acce\*'der en Perl. Il y a quatre re\*`gles importantes pour manipuler les re\*'fe\*'rences\ : deux pour les construire, et deux pour les utiliser. Une fois que vous connaissez ces re\*`gles, vous pouvez faire la plupart des choses importantes que vous devez faire avec des re\*'fe\*'rences. .SH "Cre\*'dits" .IX Header "Cre'dits" Auteur\ : Mark Jason Dominus, Plover Systems (\f(CW\*(C`mjd\-perl\-ref+@plover.com\*(C'\fR) .PP Cet article est paru a\*` l'origine dans \fIThe Perl Journal\fR ( http://www.tpj.com/ ) volume 3, # 2. Re\*'imprime\*' avec permission. .PP Le titre original e\*'tait \fIUnderstand References Today\fR (\fIComprendre les re\*'fe\*'rences aujourd'hui\fR). .Sh "Distribution conditions" .IX Subsection "Distribution conditions" Copyright 1998 The Perl Journal ( http://www.tpj.com/ ). .PP This documentation is free; you can redistribute it and/or modify it under the same terms as Perl itself. .PP Irrespective of its distribution, all code examples in these files are hereby placed into the public domain. You are permitted and encouraged to use this code in your own programs for fun or for profit as you see fit. A simple comment in the code giving credit would be courteous but is not required. .Sh "Conditions de distribution" .IX Subsection "Conditions de distribution" Copyright 1998 The Perl Journal ( http://www.tpj.com/ ). .PP Cette documentation est libre ; vous pouvez la redistribuer et/ou la modifier sous les me\*^mes conditions que Perl lui\-me\*^me. .PP Quel que soit leur mode de distribution, tous les exemples de code de ces fichiers sont par ce document place\*'s dans le domaine public. Vous e\*^tes autorise\*' et encourage\*' a\*` utiliser ce code dans vos programmes a\*` fins commerciales ou d'amusement, comme vous le souhaitez. Un simple commentaire dans le code signalant son origine serait courtois mais n'est pas requis. .SH "TRADUCTION" .IX Header "TRADUCTION" .Sh "Version" .IX Subsection "Version" Cette traduction franc\*,aise correspond a\*` la version anglaise distribue\*'e avec perl 5.8.8. Pour en savoir plus concernant ces traductions, consultez . .Sh "Traducteur" .IX Subsection "Traducteur" Traduction initiale\ : Ronan Le Hy (\f(CW\*(C`rlehy@free.fr\*(C'\fR). Mise a\*` jour\ : Paul Gaborit (\f(CW\*(C`paul.gaborit at enstimac.fr\*(C'\fR). .Sh "Relecture" .IX Subsection "Relecture" Personne pour l'instant.