.\" Automatically generated by Pod::Man 2.06 (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 "PERLOP 1" .TH PERLOP 1 "2006-03-03" "DocFr" "User Contributed Perl Documentation" .SH "NAME/NOM" .IX Header "NAME/NOM" perlop \- Ope\*'rateurs Perl et priorite\*' .SH "SYNOPSIS" .IX Header "SYNOPSIS" Le tableau suivant pre\*'sente les ope\*'rateurs Perl et leur priorite\*', du plus prioritaire au moins prioritaire. Remarquez que tous les ope\*'rateurs emprunte\*'s au C gardent le me\*^me ordre de priorite\*' entre eux me\*^me lorsque ces priorite\*'s sont le\*'ge\*`rement tordues. (Cela rend plus simple l'apprentissage de Perl par les programmeurs C.) A\*` quelques exceptions pre\*`s, tous ces ope\*'rateurs agissent sur des valeurs scalaires et pas sur des tableaux de valeurs. .PP .Vb 10 \& gauche termes et ope\*'rateurs de listes (leftward) \& gauche \-> \& nonassoc ++ \-\- \& droite ** \& droite ! ~ \e et + et \- unaires \& gauche =~ !~ \& gauche * / % x \& gauche + \- . \& gauche << >> \& nonassoc ope\*'rateurs nomme\*'s unaires \& nonassoc < > <= >= lt gt le ge \& nonassoc == != <=> eq ne cmp \& gauche & \& gauche | ^ \& gauche && \& gauche || \& nonassoc .. ... \& droite ?: \& droite = += \-= *= etc. \& gauche , => \& nonassoc ope\*'rateurs de listes (rightward) \& droite not \& gauche and \& gauche or xor .Ve .PP Dans les sections qui suivent, ces ope\*'rateurs sont pre\*'sente\*'s par ordre de priorite\*'. .PP De nombreux ope\*'rateurs peuvent e\*^tre rede\*'finis pour des objets. Voir overload. .SH "DESCRIPTION" .IX Header "DESCRIPTION" .Sh "Termes et ope\*'rateurs de listes (leftward)" .IX Subsection "Termes et ope'rateurs de listes (leftward)" Un \s-1TERME\s0 a la plus haute priorite\*' en Perl. Cela inclut les variables, les apostrophes et autres ope\*'rateurs style apostrophe, les expressions entre parenthe\*`ses et n'importe quelle fonction dont les arguments sont donne\*'s entre parenthe\*`ses. En fait, ce ne sont pas vraiment des fonctions, juste des ope\*'rateurs de listes et des ope\*'rateurs unaires qui se comportent comme des fonctions parce que vous avez mis des parenthe\*`ses autour des arguments. Tout cela est documente\*' dans perlfunc. .PP Si un ope\*'rateur de liste (\fIprint()\fR, etc.) ou un ope\*'rateur unaire (\fIchdir()\fR, etc.) est directement suivi par une parenthe\*`se gauche, l'ope\*'rateur et les arguments entre parenthe\*`ses se voient attribue\*'s la priorite\*' la plus haute exactement comme un appel de fonction. .PP En l'absence de parenthe\*`ses, la priorite\*' des ope\*'rateurs de liste comme \&\f(CW\*(C`print\*(C'\fR, \f(CW\*(C`sort\*(C'\fR ou \f(CW\*(C`chmod\*(C'\fR n'est ni tre\*`s haute ni tre\*`s basse et de\*'pend de ce qu'il y a a\*` gauche et/ou a\*` droite de l'ope\*'rateur. Par exemple, dans\ : .PP .Vb 2 \& @ary = (1, 3, sort 4, 2); \& print @ary; # affiche 1324 .Ve .PP la virgule a\*` droite du tri (sort) est e\*'value\*'e avant le tri (sort) alors que la virgule de gauche est e\*'value\*'e apre\*`s. En d'autres termes, un ope\*'rateur de listes a tendance a\*` manger tous les arguments qui le suit et a\*` se comporter comme un simple \s-1TERME\s0 par rapport a\*` l'expression qui le pre\*'ce\*`de. Faites attention aux parenthe\*`ses\ : .PP .Vb 3 \& # L'e\*'valuation de exit a lieu avant le print ! \& print($foo, exit); # Pas vraiment ce que vous vouliez. \& print $foo, exit; # Ni dans ce cas. \& \& # L'e\*'valuation de print a lieu avant le exit. \& (print $foo), exit; # C'est ce que vous voulez. \& print($foo), exit; # Ici aussi. \& print ($foo), exit; # Et encore dans ce cas. .Ve .PP Remarquez aussi que\ : .PP .Vb 1 \& print ($foo & 255) + 1, "\en"; .Ve .PP ne donne probablement pas ce que vous attendiez a\*` priori. Voir les \&\*(L"Ope\*'rateurs unaires nomme\*'s\*(R" pour plus de de\*'tails. .PP Sont aussi reconnus comme des termes les constructions \f(CW\*(C`do {}\*(C'\fR et \f(CW\*(C`eval {}\*(C'\fR, les appels a\*` des subroutines ou a\*` des me\*'thodes ainsi que les constructeurs anonymes \f(CW\*(C`[]\*(C'\fR et \f(CW\*(C`{}\*(C'\fR. .PP Voir aussi \*(L"Ope\*'rateurs apostrophe et type apostrophe\*(R" a\*` la fin de cette section mais aussi \*(L"S\*(R"\*(L" in \*(R"Les ope\*'rateurs d'E. .Sh "L'ope\*'rateur fle\*`che" .IX Subsection "L'ope'rateur fle`che" Comme en C et en \*(C+, "\f(CW\*(C`\->\*(C'\fR" est un ope\*'rateur de de\*'re\*'fe\*'rencement infixe. Si du co\*^te\*' droit on trouve soit \f(CW\*(C`[...]\*(C'\fR, soit \f(CW\*(C`{...}\*(C'\fR, soit \f(CW\*(C`(...)\*(C'\fR alors le co\*^te\*' gauche doit e\*^tre une re\*'fe\*'rence vraie ou symbolique vers respectivement un tableau, une table de hachage ou une subroutine (ou techniquement parlant, un emplacement capable de stocker une re\*'fe\*'rence en dur si c'est une re\*'fe\*'rence vers un tableau ou une table de hachage utilise\*'e pour une affectation). Voir perlreftut et perlref. .PP Par contre, si le co\*^te\*' droit est un nom de me\*'thode ou une simple variable scalaire contenant un nom de me\*'thode ou une re\*'fe\*'rence vers une subroutine alors le co\*^te\*' gauche doit e\*^tre soit un objet (une re\*'fe\*'rence be\*'nie \*(-- par \&\fIbless()\fR) soit un nom de classe (c'est a\*` dire un nom de package). Voir perlobj. .Sh "Auto\-incre\*'mentation et Auto\-de\*'cre\*'mentation" .IX Subsection "Auto-incre'mentation et Auto-de'cre'mentation" \&\*(L"++\*(R" et \*(L"\-\-\*(R" fonctionne comme en C. Place\*'s avant la variable, ils incre\*'mentent ou de\*'cre\*'mentent la variable avant de retourner sa valeur. Place\*'s apre\*`s, ils incre\*'mentent ou de\*'cre\*'mentent la variable apre\*`s avoir retourner sa valeur. .PP De plus, l'ope\*'rateur d'auto\-incre\*'mentation inclut un comportement magique. Si vous incre\*'mentez une variable nume\*'rique ou qui a de\*'ja\*` e\*'te\*' utilise\*'e dans un contexte nume\*'rique, vous obtenez l'incre\*'ment normal. Si, par contre, la variable n'a e\*'te\*' utilise\*'e que dans un contexte de chai\*^ne et correspond au motif \f(CW\*(C`/^[a\-zA\-Z]*[0\-9]*$/\*(C'\fR, l'incre\*'mentation a lieu sur la chai\*^ne elle\-me\*^me en pre\*'servant les caracte\*`res dans leur intervalle et en ge\*'rant les e\*'ventuelles retenues : .PP .Vb 4 \& print ++($foo = '99'); # affiche '100' \& print ++($foo = 'a0'); # affiche 'a1' \& print ++($foo = 'Az'); # affiche 'Ba' \& print ++($foo = 'zz'); # affiche 'aaa' .Ve .PP L'ope\*'rateur d'auto\-de\*'cre\*'mentation n'est pas magique. .Sh "Puissance" .IX Subsection "Puissance" L'ope\*'rateur binaire \*(L"**\*(R" est l'ope\*'rateur puissance. Remarquez qu'il est plus prioritaire que le moins unaire donc \-2**4 signifie \-(2**4) et non pas (\-2)**4. (Il est imple\*'mente\*' par la fonction C \fIpow\fR\|(3) qui travaille re\*'ellement sur des doubles en interne.) .Sh "Ope\*'rateurs symboliques unaires" .IX Subsection "Ope'rateurs symboliques unaires" L'ope\*'rateur unaire \*(L"!\*(R" est la ne\*'gation logique, i.e. \*(L"non\*(R". Voir aussi \f(CW\*(C`not\*(C'\fR pour une version moins prioritaire de cet ope\*'ration. .PP L'ope\*'rateur unaire \*(L"\-\*(R" est la ne\*'gation arithme\*'tique si l'ope\*'rande est nume\*'rique. Si l'ope\*'rande est un identificateur, il retourne une chai\*^ne constitue\*'e du signe moins suivi de l'identificateur. Si la chai\*^ne commence par un plus ou un moins, la valeur retourne\*'e est la chai\*^ne commenc\*,ant par le signe oppose\*'. L'un des effets de ces re\*`gles est que \f(CW\*(C`\-bareword\*(C'\fR est e\*'quivalent a\*` \&\f(CW"\-bareword"\fR. .PP L'ope\*'rateur unaire \*(L"~\*(R" effectue la ne\*'gation bit a\*` bit, i.e. le comple\*'ment a\*` 1. Par exemple \f(CW\*(C`0666 & ~027\*(C'\fR vaut 0640. (Voir aussi \*(L"Arithme\*'tique entie\*`re\*(R" et \*(L"Ope\*'rateurs bit a\*` bit sur les chai\*^nes\*(R".) Notez que la taille du re\*'sultat de\*'pend de la plate-forme\ : ~0 a une taille de 32 bits sur une plate-forme 32\-bit et une taille de 64 bits sur une plate-forme 64\-bit. Donc si vous attendez une certain nombre de bits, souvenez-vous d'utiliser l'ope\*'rateur & pour masquer les bits en exce\*`s. .PP L'ope\*'rateur unaire \*(L"+\*(R" n'a aucun effet me\*^me sur les chai\*^nes. Il est pratique pour se\*'parer syntaxiquement un nom de fonction d'une expression entre parenthe\*`ses qui autrement aurait e\*'te\*' interpre\*'te\*'e comme la liste comple\*`te des arguments de la fonction. (Voir les exemples de \*(L"Termes et ope\*'rateurs de listes (leftward)\*(R".) .PP L'ope\*'rateur unaire \*(L"\e\*(R" cre\*'e une re\*'fe\*'rence vers ce qui le suit. Voir perlref. Ne confondez pas ce comportement avec celui de la barre oblique inverse\*'e (backslash) a\*` l'inte\*'rieur d'une chai\*^ne bien que les deux formes proposent une sorte de protection contre l'interpre\*'tation de ce qui les suit. .Sh "Ope\*'rateurs d'application d'expressions rationnelles" .IX Subsection "Ope'rateurs d'application d'expressions rationnelles" L'ope\*'rateur binaire \*(L"=~\*(R" applique un motif de reconnaissance a\*` une expression scalaire. Plusieurs ope\*'rations cherchent ou modifient la chai\*^ne \f(CW$_\fR par de\*'faut. Cet ope\*'rateur permet d'appliquer cette sorte d'ope\*'rations a\*` d'autres chai\*^nes. L'argument de droite est le motif de recherche, de substitution ou de remplacement. L'argument de gauche est ce qui est suppose\*' e\*^tre cherche\*', substitue\*' ou remplace\*' a\*` la place de la valeur par de\*'faut \f(CW$_\fR. Dans un contexte scalaire, la valeur retourne\*'e indique ge\*'ne\*'ralement le succe\*`s de l'ope\*'ration. Le comportement dans un contexte de liste de\*'pend de chaque ope\*'rateur. Voir \*(L"Ope\*'rateurs apostrophe et type apostrophe\*(R". .PP Si l'argument de droite est une expression pluto\*^t qu'un motif de recherche, de substitution ou de remplacement, il est interpre\*'te\*' comme un motif de recherche lors de l'exe\*'cution. Cela peut e\*^tre moins efficace qu'une recherche explicite puisque le motif doit e\*^tre compile\*' a\*` chaque fois que l'expression est e\*'value\*'e. .PP L'ope\*'rateur binaire \*(L"!~\*(R" est exactement comme \*(L"=~\*(R" sauf que la valeur retourne\*'e est le contraire au sens logique. .Sh "Ope\*'rateurs type multiplication" .IX Subsection "Ope'rateurs type multiplication" L'ope\*'rateur binaire \*(L"*\*(R" multiplie deux nombres. .PP L'ope\*'rateur binaire \*(L"/\*(R" divise deux nombres. .PP L'ope\*'rateur binaire \*(L"%\*(R" calcule le modulo de deux nombres. Soit deux ope\*'randes entiers donne\*'s \f(CW$a\fR et \f(CW$b\fR\ : si \f(CW$b\fR est positif alors \f(CW\*(C`$a % $b\*(C'\fR vaut \&\f(CW$a\fR moins le plus grand multiple de \f(CW$b\fR qui n'est pas plus grand que \&\f(CW$a\fR. Si \f(CW$b\fR est ne\*'gatif alors \f(CW\*(C`$a % $b\*(C'\fR vaut \f(CW$a\fR moins le plus petit multiple de \f(CW$b\fR qui n'est pas plus petit que \f(CW$a\fR (i.e. le re\*'sultat est plus petit ou e\*'gal a\*` ze\*'ro). Remarquez que lorsque vous e\*^tes dans la porte\*'e de \&\f(CW\*(C`use integer\*(C'\fR, \*(L"%\*(R" vous donne acce\*`s directement a\*` l'ope\*'rateur modulo tel qu'il est de\*'fini par votre compilateur C. Cet ope\*'rateur n'est pas tre\*`s bien de\*'fini pour des ope\*'randes ne\*'gatifs mais il s'exe\*'cute plus rapidement. .PP L'ope\*'rateur binaire \*(L"x\*(R" est l'ope\*'rateur de re\*'pe\*'tition. Dans un contexte scalaire, il retourne une chai\*^ne constitue\*'e de son ope\*'rande de gauche re\*'pe\*'te\*' le nombre de fois spe\*'cifie\*' par son ope\*'rande de droite. Dans un contexte de liste, si l'ope\*'rande de gauche est entre parenthe\*`ses, il re\*'pe\*`te la liste. .PP .Vb 1 \& print '\-' x 80; # affiche une ligne de '\-' \& \& print "\et" x ($tab/8), ' ' x ($tab%8); # tab over \& \& @ones = (1) x 80; # une liste de quatre\-vingt 1. \& @ones = (5) x @ones; # place tous les e\*'le\*'ments a\*` 5. .Ve .Sh "Ope\*'rateurs type addition" .IX Subsection "Ope'rateurs type addition" L'ope\*'rateur binaire \*(L"+\*(R" retourne la somme de deux nombres. .PP L'ope\*'rateur binaire \*(L"\-\*(R" retourne la diffe\*'rence de deux nombres. .PP L'ope\*'rateur binaire \*(L".\*(R" concate\*`ne deux chai\*^nes. .Sh "Ope\*'rateurs de de\*'calages" .IX Subsection "Ope'rateurs de de'calages" L'ope\*'rateur binaire \*(L"<<\*(R" retourne la valeur de son ope\*'rande de gauche de\*'cale\*'e vers la gauche d'un nombre de bits spe\*'cifie\*' par son ope\*'rande de droite. Les arguments devraient e\*^tre des entiers. (Voir aussi \*(L"Arithme\*'tique entie\*`re\*(R".) .PP L'ope\*'rateur binaire \*(L">>\*(R" retourne la valeur de son ope\*'rande de gauche de\*'cale\*'e vers la droite d'un nombre de bits spe\*'cifie\*' par son ope\*'rande de droite. Les arguments devraient e\*^tre des entiers. (Voir aussi \*(L"Arithme\*'tique entie\*`re\*(R".) .Sh "Ope\*'rateurs unaires nomme\*'s" .IX Subsection "Ope'rateurs unaires nomme's" Les diffe\*'rents ope\*'rateurs unaire nomme\*'s sont traite\*'s comme des fonctions a\*` un argument avec des parenthe\*`ses optionnelles. Ceci inclut les ope\*'rateurs de tests de fichiers comme \f(CW\*(C`\-f\*(C'\fR, \f(CW\*(C`\-M\*(C'\fR, etc. Voir perlfunc. .PP Si un ope\*'rateur de liste (\fIprint()\fR, etc.) ou un ope\*'rateur unaire (\fIchdir()\fR, etc.) est suivi d'une parenthe\*`se ouvrante, l'ope\*'rateur et ses arguments entre parenthe\*`ses sont conside\*'re\*'s comme de priorite\*' la plus haute exactement comme n'importe quel appel a\*` une fonction. Exemples\ : .PP .Vb 4 \& chdir $foo || die; # (chdir $foo) || die \& chdir($foo) || die; # (chdir $foo) || die \& chdir ($foo) || die; # (chdir $foo) || die \& chdir +($foo) || die; # (chdir $foo) || die .Ve .PP mais puisque * est plus prioritaire que ||\ : .PP .Vb 4 \& chdir $foo * 20; # chdir ($foo * 20) \& chdir($foo) * 20; # (chdir $foo) * 20 \& chdir ($foo) * 20; # (chdir $foo) * 20 \& chdir +($foo) * 20; # chdir ($foo * 20) \& \& rand 10 * 20; # rand (10 * 20) \& rand(10) * 20; # (rand 10) * 20 \& rand (10) * 20; # (rand 10) * 20 \& rand +(10) * 20; # rand (10 * 20) .Ve .PP Voir aussi \*(L"Termes et ope\*'rateurs de listes (leftward)\*(R". .Sh "Ope\*'rateurs de comparaisons" .IX Subsection "Ope'rateurs de comparaisons" L'ope\*'rateur binaire \*(L"<\*(R" renvoie vrai si son ope\*'rande gauche est nume\*'riquement plus petit que son ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L">\*(R" renvoie vrai si son ope\*'rande gauche est nume\*'riquement plus grand que son ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L"<=\*(R" renvoie vrai si son ope\*'rande gauche est nume\*'riquement plus petit ou e\*'gal que son ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L">=\*(R" renvoie vrai si son ope\*'rande gauche est nume\*'riquement plus grand ou e\*'gal que son ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L"lt\*(R" renvoie vrai si son ope\*'rande gauche est alphabe\*'tiquement plus petit que son ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L"gt\*(R" renvoie vrai si son ope\*'rande gauche est alphabe\*'tiquement plus grand que son ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L"le\*(R" renvoie vrai si son ope\*'rande gauche est alphabe\*'tiquement plus petit ou e\*'gal que son ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L"ge\*(R" renvoie vrai si son ope\*'rande gauche est alphabe\*'tiquement plus grand ou e\*'gal que son ope\*'rande droit. .Sh "Ope\*'rateurs d'e\*'galite\*'" .IX Subsection "Ope'rateurs d'e'galite'" L'ope\*'rateur binaire \*(L"==\*(R" renvoie vrai si l'ope\*'rande gauche est nume\*'riquement e\*'gal a\*` l'ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L"!=\*(R" renvoie vrai si l'ope\*'rande gauche n'est pas nume\*'riquement e\*'gal a\*` l'ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L"<=>\*(R" renvoie \-1, 0 ou 1 selon que l'ope\*'rande gauche est nume\*'riquement et respectivement plus petit, e\*'gal ou plus grand que l'ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L"eq\*(R" renvoie vrai si l'ope\*'rande gauche est e\*'gal alphabe\*'tiquement a\*` l'ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L"ne\*(R" renvoie vrai si l'ope\*'rande gauche n'est pas e\*'gal alphabe\*'tiquement a\*` l'ope\*'rande droit. .PP L'ope\*'rateur binaire \*(L"cmp\*(R" renvoie \-1, 0 ou 1 selon que l'ope\*'rande gauche est alphabe\*'tiquement et respectivement plus petit, e\*'gal ou plus grand que l'ope\*'rande droit. .PP \&\*(L"lt\*(R", \*(L"le\*(R", \*(L"ge\*(R", \*(L"gt\*(R" et \*(L"cmp\*(R" utilise l'ordre de tri (collation) spe\*'cifie\*' par le locale courant si \f(CW\*(C`use locale\*(C'\fR est actif. Voir perllocale. .Sh "Ope\*'rateur Et bit a\*` bit" .IX Subsection "Ope'rateur Et bit a` bit" L'ope\*'rateur binaire \*(L"&\*(R" renvoie le re\*'sultat d'un \s-1ET\s0 bit a\*` bit entre ses ope\*'randes. (Voir aussi \*(L"Arithme\*'tique entie\*`re\*(R" et \*(L"Ope\*'rateurs bit a\*` bit sur les chai\*^nes\*(R".) .Sh "Ope\*'rateurs Ou et Ou exclusif bit a\*` bit" .IX Subsection "Ope'rateurs Ou et Ou exclusif bit a` bit" L'ope\*'rateur binaire \*(L"|\*(R" renvoie le re\*'sultat d'un \s-1OU\s0 bit a\*` bit entre ses deux ope\*'randes. (Voir aussi \*(L"Arithme\*'tique entie\*`re\*(R" et \*(L"Ope\*'rateurs bit a\*` bit sur les chai\*^nes\*(R".) .PP L'ope\*'rateur binaire \*(L"^\*(R" renvoie le re\*'sultat d'un \s-1OU\s0 \s-1EXCLUSIF\s0 (\s-1XOR\s0) bit a\*` bit entre ses deux ope\*'randes. (Voir aussi \*(L"Arithme\*'tique entie\*`re\*(R" et \*(L"Ope\*'rateurs bit a\*` bit sur les chai\*^nes\*(R".) .Sh "Et logique style C" .IX Subsection "Et logique style C" L'ope\*'rateur binaire \*(L"&&\*(R" calcule un \s-1ET\s0 logique rapide. Cela signifie que si l'ope\*'rande gauche est faux, l'ope\*'rande droit n'est me\*^me pas e\*'value\*'. Le contexte scalaire ou de liste se propage vers l'ope\*'rande droit si il est e\*'value\*'. .Sh "Ou logique style C" .IX Subsection "Ou logique style C" L'ope\*'rateur binaire \*(L"||\*(R" calcule un \s-1OU\s0 logique rapide. Cela signifie que si l'ope\*'rande gauche est vrai, l'ope\*'rande droit n'est me\*^me pas e\*'value\*'. Le contexte scalaire ou de liste se propage vers l'ope\*'rande droit si il est e\*'value\*'. .PP Les ope\*'rateurs \f(CW\*(C`||\*(C'\fR et \f(CW\*(C`&&\*(C'\fR diffe\*`rent du C sur un point\ : au lieu de renvoyer 0 ou 1, ils renvoient la dernie\*`re valeur e\*'value\*'e. Donc, un moyen raisonnablement portable de trouver le re\*'pertoire home (en supposant que ce ne soit pas \*(L"0\*(R") peut e\*^tre\ : .PP .Vb 2 \& $home = $ENV{'HOME'} || $ENV{'LOGDIR'} || \& (getpwuid($<))[7] || die "You're homeless!\en"; .Ve .PP En particulier, cela signifie que vous ne devriez pas les utiliser pour choisir entre deux agre\*'gats dans une .PP .Vb 3 \& @a = @b || @c; # c'est pas bon \& @a = scalar(@b) || @c; # voila ce que c\*,a signifie \& @a = @b ? @b : @c; # cela marche tre\*`s bien par contre .Ve .PP Pour remplacer d'une manie\*`re plus lisible l'usage de \f(CW\*(C`&&\*(C'\fR et \f(CW\*(C`||\*(C'\fR pour contro\*^ler un flot d'ope\*'rations, Perl propose les ope\*'rateurs \f(CW\*(C`and\*(C'\fR et \f(CW\*(C`or\*(C'\fR (voir plus bas). Le comportement d'e\*'valuation rapide est le me\*^me. Par contre, la priorite\*' de \*(L"and\*(R" et \*(L"or\*(R" est plus basse, vous pouvez donc les utiliser apre\*`s les ope\*'rateurs de listes sans ajouter de parenthe\*`ses\ : .PP .Vb 2 \& unlink "alpha", "beta", "gamma" \& or gripe(), next LINE; .Ve .PP Avec les ope\*'rateurs a\*` la C, vous auriez du\*^ l'e\*'crire\ : .PP .Vb 2 \& unlink("alpha", "beta", "gamma") \& || (gripe(), next LINE); .Ve .PP En revanche, l'utilisation de \*(L"or\*(R" lors d'une affectation ne donne pas ce que vous voulez; voir plus bas. .Sh "Ope\*'rateurs d'intervalle" .IX Subsection "Ope'rateurs d'intervalle" L'ope\*'rateur binaire \*(L"..\*(R" est l'ope\*'rateur d'intervalle qui est en fait deux ope\*'rateurs totalement diffe\*'rents selon le contexte. Dans un contexte de liste, il renvoie un tableau de valeurs commenc\*,ant a\*` la valeur de son ope\*'rande gauche et se terminant a\*` la valeur de son ope\*'rande droit (par pas de 1). Si la valeur de gauche est plus petite que la valeur de droite, il retourne un tableau vide. C'est pratique pour e\*'crire des boucles \f(CW\*(C`foreach (1..10)\*(C'\fR et pour des ope\*'rations de remplacement sur des tableaux. Dans l'imple\*'mentation actuelle, aucun tableau temporaire n'est ge\*'ne\*'re\*' lorsque l'ope\*'rateur d'intervalle est utilise\*' comme expression de boucles \f(CW\*(C`foreach\*(C'\fR mais les vieilles versions de Perl peuvent consommer e\*'norme\*'ment de me\*'moire lorsque vous e\*'crivez quelque chose comme\ : .PP .Vb 3 \& for (1 .. 1_000_000) { \& # code \& } .Ve .PP Dans un contexte scalaire, \*(L"..\*(R" renvoie une valeur boole\*'enne. L'ope\*'rateur est bi-stable comme un interrupteur et simule l'ope\*'rateur d'intervalle de ligne (virgule) de \fBsed\fR, de \fBawk\fR et d'autres e\*'diteurs. Chaque ope\*'rateur \*(L"..\*(R" conserve en me\*'moire son propre e\*'tat boole\*'en. Il reste faux tant que son ope\*'rande gauche est faux. Puis de\*`s que son ope\*'rande gauche devient vrai, il reste vrai jusqu'a\*` ce que son ope\*'rande droit soit vrai. \fIAPRE\*`S\fR quoi, l'ope\*'rateur d'intervalle redevient faux. Il ne redevient faux que le prochaine fois que l'ope\*'rateur d'intervalle est e\*'value\*'. Il peut tester l'ope\*'rande droit et devenir faux lors de la me\*^me e\*'valuation ou\*` il devient vrai (comme dans \&\fBawk\fR) mais il retournera encore une fois vrai. Si vous ne voulez pas qu'il teste l'ope\*'rande droit avant la prochaine e\*'valuation (comme dans \fBsed\fR), utilisez trois points (\*(L"...\*(R") a\*` la place de deux. Pour tout le reste, \*(L"...\*(R" se comporte exactement comme \*(L"..\*(R". .PP L'ope\*'rande droit n'est pas e\*'value\*' tant que l'ope\*'rateur est dans l'e\*'tat \*(L"faux\*(R" et l'ope\*'rande gauche n'est pas e\*'value\*' tant que l'ope\*'rateur est dans l'e\*'tat \&\*(L"vrai\*(R". La priorite\*' de l'ope\*'rateur intervalle est un peu plus basse que celle de || et &&. La valeur retourne\*'e est soit la chai\*^ne vide pour signifier \*(L"faux\*(R" soit un nume\*'ro de se\*'quence (commenc\*,ant a\*` 1) pour \*(L"vrai\*(R". Le dernier nume\*'ro de se\*'quence d'un intervalle est suivi de la chai\*^ne \*(L"E0\*(R" ce qui ne perturbe pas sa valeur nume\*'rique mais vous donne quelque chose a\*` chercher si vous voulez exclure cette dernie\*`re valeur. Vous pouvez exclure la premie\*`re valeur en demandant une valeur supe\*'rieure a\*` 1. Si l'un des ope\*'randes de l'ope\*'rateur intervalle pris dans un contexte scalaire est une expression constante, cette ope\*'rande est implicitement compare\*' a\*` la variable \f(CW$.\fR (le nume\*'ro de ligne courant). Exemples\ : .PP Comme ope\*'rateur scalaire\ : .PP .Vb 3 \& if (101 .. 200) { print; } # affiche la seconde centaine de lignes \& next line if (1 .. /^$/); # saut des lignes d'en\-te\*^tes \& s/^/> / if (/^$/ .. eof()); # place le corps comme citation \& \& # analyse d'e\-mail \& while (<>) { \& $in_header = 1 .. /^$/; \& $in_body = /^$/ .. eof(); \& # faire quelque chose avec... \& } continue { \& close ARGV if eof; # re\*'initialisation de $. a\*` chaque fichier \& } .Ve .PP Comme ope\*'rateur de liste\ : .PP .Vb 3 \& for (101 .. 200) { print; } # affiche $_ 100 fois \& @foo = @foo[0 .. $#foo]; # un no\-op cou\*^teux \& @foo = @foo[$#foo\-4 .. $#foo]; # extraction des 5 derniers items .Ve .PP L'ope\*'rateur intervalle (dans un contexte de liste) utilise l'algorithme magique d'auto\-incre\*'mentation si les ope\*'randes sont des chai\*^nes. Vous pouvez e\*'crire\ : .PP .Vb 1 \& @alphabet = ('A' .. 'Z'); .Ve .PP pour obtenir toutes les lettres de l'alphabet ou .PP .Vb 1 \& $hexdigit = (0 .. 9, 'a' .. 'f')[$num & 15]; .Ve .PP pour obtenir les chiffres hexade\*'cimaux ou .PP .Vb 1 \& @z2 = ('01' .. '31'); print $z2[$mjour]; .Ve .PP pour obtenir des dates avec des ze\*'ros. Si la valeur finale donne\*'e n'est pas dans la se\*'quence produite par l'incre\*'mentation magique, la se\*'quence continue jusqu'a\*` ce que la prochaine valeur soit plus longue que la valeur finale spe\*'cifie\*'e. .Sh "L'ope\*'rateur conditionnel" .IX Subsection "L'ope'rateur conditionnel" L'ope\*'rateur \*(L"?:\*(R" est l'ope\*'rateur conditionnel exactement comme en C. Il travaille presque comme un si\-alors\-sinon. Si l'argument avant le ? est vrai, l'argument avant le : est renvoye\*' sinon l'argument apre\*`s le : est renvoye\*'. Par exemple\ : .PP .Vb 2 \& printf "J'ai %d chien%s.\en", $n, \& ($n == 1) ? '' : "s"; .Ve .PP Le contexte scalaire ou de liste se propage au second ou au troisie\*`me argument quelque soit le choix. .PP .Vb 3 \& $a = $ok ? $b : $c; # un scalaire \& @a = $ok ? @b : @c; # un tableau \& $a = $ok ? @b : @c; # oups, juste un compte ! .Ve .PP On peut affecter quelque chose a\*` l'ope\*'rateur si le second \s-1ET\s0 le troisie\*`me arguments sont des lvalues le\*'gales (ce qui signifie qu'on peut leur affecter quelque chose) : .PP .Vb 1 \& ($a_or_b ? $a : $b) = $c; .Ve .PP Il n'y a aucune garantie que cela contribue a\*` la lisibilite\*' de votre programme. .PP Puisque l'ope\*'rateur produit un re\*'sultat affectable, l'usage d'affectation sans parenthe\*`se peut amener quelques proble\*`mes. Par exemple, le ligne suivante\ : .PP .Vb 1 \& $a % 2 ? $a += 10 : $a += 2 .Ve .PP signifie re\*'ellement\ : .PP .Vb 1 \& (($a % 2) ? ($a += 10) : $a) += 2 .Ve .PP au lieu de\ : .PP .Vb 1 \& ($a % 2) ? ($a += 10) : ($a += 2) .Ve .PP Cela aurait probablement pu e\*^tre e\*'crit plus simplement\ : .PP .Vb 1 \& $a += ($a % 2) ? 10 : 2; .Ve .Sh "Ope\*'rateurs d'affectation" .IX Subsection "Ope'rateurs d'affectation" \&\*(L"=\*(R" est l'ope\*'rateur habituel d'affectation. .PP Les ope\*'rateurs d'affectation fonctionnent comme en C. Donc\ : .PP .Vb 1 \& $a += 2; .Ve .PP est e\*'quivalent a\*`\ : .PP .Vb 1 \& $a = $a + 2; .Ve .PP quoique sans dupliquer les e\*'ventuels effets de bord que le de\*'re\*'fe\*'rencement de la lvalue pourraient de\*'clencher, comme par exemple avec \fItie()\fR. Les autres ope\*'rateurs d'affectation fonctionnent de la me\*^me manie\*`re. Voici ceux qui sont reconnus\ : .PP .Vb 4 \& **= += *= &= <<= &&= \& \-= /= |= >>= ||= \& .= %= ^= \& x= .Ve .PP Remarque: bien que regroupe\*'s par famille, tous ces ope\*'rateurs ont la me\*^me priorite\*' que l'affectation. .PP Au contraire du C, les ope\*'rateurs d'affectation produisent une lvalue valide. Modifier une affectation est e\*'quivalent a\*` faire l'affectation puis a\*` modifier la variable qui vient d'e\*^tre affecte\*'e. C'est tre\*`s pratique pour modifier une copie de quelque chose comme dans\ : .PP .Vb 1 \& ($tmp = $global) =~ tr [A\-Z] [a\-z]; .Ve .PP De me\*^me\ : .PP .Vb 1 \& ($a += 2) *= 3; .Ve .PP est e\*'quivalent a\*`\ : .PP .Vb 2 \& $a += 2; \& $a *= 3; .Ve .PP De manie\*`re similaire, une affectation vers une liste dans un contexte de liste produit la liste des lvalues affecte\*'es et dans un contexte scalaire produit le nombre d'e\*'le\*'ments pre\*'sents dans l'ope\*'rande de droite de l'affectation. .Sh "Ope\*'rateur virgule" .IX Subsection "Ope'rateur virgule" L'ope\*'rateur binaire \*(L",\*(R" est l'ope\*'rateur virgule. Dans un contexte scalaire, il e\*'value son ope\*'rande gauche et jette le re\*'sultat puis il e\*'value son ope\*'rande droit et retourne cette valeur. C'est exactement comme l'ope\*'rateur virgule du C. .PP Dans un contexte de liste, c'est tout simplement le se\*'parateur d'arguments de la liste. Il inse\*`re ses deux ope\*'randes dans la liste. .PP Le digramme => est un synonyme de l'ope\*'rateur virgule. C'est pratique pour indiquer que les arguments fonctionnent par paires. Depuis la version 5.001, il contraint le mot a\*` sa gauche a\*` e\*^tre interpre\*'te\*' comme une chai\*^ne. .Sh "Ope\*'rateurs de listes (Rightward)" .IX Subsection "Ope'rateurs de listes (Rightward)" Du co\*^te\*' droit d'un ope\*'rateur de liste, il a une priorite\*' tre\*`s basse qui permet de mai\*^triser toutes les expressions pre\*'sentes se\*'pare\*'es par des virgules. Les seuls ope\*'rateurs de priorite\*' infe\*'rieure sont les ope\*'rateurs logiques \*(L"and\*(R", \&\*(L"or\*(R" et \*(L"not\*(R" qui peuvent e\*^tre utiliser pour e\*'valuer plusieurs appels a\*` des ope\*'rateurs de liste sans l'ajout de parenthe\*`ses supple\*'mentaires : .PP .Vb 2 \& open HANDLE, "filename" \& or die "Can't open: $!\en"; .Ve .PP Voir aussi la discussion sur les ope\*'rateurs de liste dans \*(L"Termes et ope\*'rateurs de liste (leftward)\*(R". .Sh "Non (not) logique" .IX Subsection "Non (not) logique" L'ope\*'rateur unaire \*(L"not\*(R" renvoie la ne\*'gation logique de l'expression a\*` sa droite. Il est e\*'quivalent a\*` \*(L"!\*(R" sauf sa priorite\*' beaucoup plus basse. .Sh "Et (et) logique" .IX Subsection "Et (et) logique" L'ope\*'rateur binaire \*(L"and\*(R" renvoie la conjonction logique des deux expressions qui l'entourent. Il est e\*'quivalent a\*` && sauf sa priorite\*' beaucoup plus basse. Cela signifie qu'il est rapide: i.e., l'expression de droite est e\*'value\*'e uniquement si celle de gauche est vraie. .Sh "Ou (or) et ou exclusif (xor) logique" .IX Subsection "Ou (or) et ou exclusif (xor) logique" L'ope\*'rateur binaire \*(L"or\*(R" renvoie la disjonction logique des deux expressions qui l'entourent. Il est e\*'quivalent a\*` || sauf sa priorite\*' beaucoup plus basse. C'est pratique pour contro\*^ler une suite d'ope\*'rations\ : .PP .Vb 1 \& print FH $data or die "Can't write to FH: $!"; .Ve .PP Cela signifie qu'il est rapide: i.e., l'expression de droite est e\*'value\*'e uniquement si celle de gauche est fausse. A\*` cause de sa priorite\*', vous devriez l'e\*'viter dans les affectations et ne l'utiliser que pour du contro\*^le d'ope\*'rations. .PP .Vb 3 \& $a = $b or $c; # bug: c'est pas bon \& ($a = $b) or $c; # voila ce que c\*,a signifie \& $a = $b || $c; # il vaut mieux l'e\*'crire ainsi .Ve .PP Au contraire, lorsque l'affectation est dans un contexte de liste et que vous voulez utiliser \*(L"||\*(R" pour du contro\*^le, il vaut mieux utiliser \*(L"or\*(R" pour que l'affectation soit prioritaire. .PP .Vb 2 \& @info = stat($file) || die; # hola\*`, sens scalaire de stat ! \& @info = stat($file) or die; # meilleur, @info rec\*,oit ce qu'il faut .Ve .PP Bien su\*^r, il est toujours possible d'utiliser les parenthe\*`ses. .PP L'ope\*'rateur binaire \*(L"xor\*(R" renvoie le ou exclusif des deux expressions qui l'entourent. Il ne peut e\*'videmment pas e\*^tre rapide. .Sh "Ope\*'rateurs C manquant en Perl" .IX Subsection "Ope'rateurs C manquant en Perl" Voici ce qui existe en C et que Perl n'a pas\ : .IP "& unaire" 8 .IX Item "& unaire" Ope\*'rateur adresse\-de. (Voir l'ope\*'rateur \*(L"\e\*(R" pour prendre une re\*'fe\*'rence.) .IP "* unaire" 8 .IX Item "* unaire" Ope\*'rateur contenu-de ou de de\*'re\*'fe\*'rencement. (Les ope\*'rateurs de de\*'re\*'fe\*'rencement de Perl sont des pre\*'fixes type\*'s\ : $, @, % et &.) .IP "(\s-1TYPE\s0)" 8 .IX Item "(TYPE)" Ope\*'rateur de conversion de type (de cast). .Sh "Ope\*'rateurs apostrophe et type apostrophe" .IX Subsection "Ope'rateurs apostrophe et type apostrophe" Bien qu'habituellement nous pensions aux apostrophes (et autres guillemets) pour des valeurs litte\*'rales, en Perl, elles fonctionnent comme des ope\*'rateurs et proposent diffe\*'rents types d'interpolation et de capacite\*'s de reconnaissance de motif. Perl fournit des caracte\*`res standard pour cela mais fournit aussi le moyen de choisir vos propres caracte\*`res. Dans la table suivante, le \f(CW\*(C`{}\*(C'\fR repre\*'sente n'importe quelle paire de de\*'limiteurs que vous aurez choisie. .PP .Vb 9 \& Standard Ge\*'ne\*'rique Signification Interpolation \& '' q{} Litte\*'rale non \& "" qq{} Litte\*'rale oui \& `` qx{} Commande oui (sauf si de\*'limiteur '') \& qw{} Liste de mots non \& // m{} Reconnaissance de motif oui (sauf si de\*'limiteur '') \& qr{} Motif oui (sauf si de\*'limiteur '') \& s{}{} Substitution oui (sauf si de\*'limiteur '') \& tr{}{} Translitte\*'ration non (voir plus bas) .Ve .PP Les de\*'limiteurs qui ne marchent pas par deux utilisent le me\*^me caracte\*`re au de\*'but et a\*` la fin par contre les quatre sortes de parenthe\*`ses (parenthe\*`ses, crochets, accolades et infe\*'rieur/supe\*'rieur) marchent par deux et peuvent e\*^tre imbrique\*'es ce qui signifie que\ : .PP .Vb 1 \& q{foo{bar}baz} .Ve .PP est la me\*^me chose que\ : .PP .Vb 1 \& 'foo{bar}baz' .Ve .PP Remarquez par contre que cela ne fonctionne pas toujours. Par exemple\ : .PP .Vb 1 \& $s = q{ if($a eq "}") ... }; # Mauvais .Ve .PP est une erreur de syntaxe. Le module \f(CW\*(C`Text::Balanced\*(C'\fR disponible sur \s-1CPAN\s0 est capable de ge\*'rer cela correctement. .PP Il peut y avoir des espace entre l'ope\*'rateur et le caracte\*`re de\*'limiteur sauf lorsque \f(CW\*(C`#\*(C'\fR est utilise\*'. \f(CW\*(C`q#foo#\*(C'\fR est interpre\*'te\*' comme la chai\*^ne \f(CW\*(C`foo\*(C'\fR alors que \f(CW\*(C`q #foo#\*(C'\fR est l'ope\*'rateur \f(CW\*(C`q\*(C'\fR suivi d'un commentaire. Ses arguments sont alors pris sur la ligne suivante. Cela permet d'e\*'crire\ : .PP .Vb 2 \& s {foo} # Remplace foo \& {bar} # par bar. .Ve .PP Pour les constructions qui re\*'alisent une interpolation, les variables commenc\*,ant par "\f(CW\*(C`$\*(C'\fR\*(L" ou \*(R"\f(CW\*(C`@\*(C'\fR" sont interpole\*'es ainsi que les se\*'quences suivantes. Dans une translitte\*'ration, seules les douze premie\*`res se\*'quences sont utilisables. .PP .Vb 11 \& \et tabulation (HT, TAB) \& \en nouvelle ligne (LF, NL) \& \er retour chariot (CR) \& \ef page suivante (FF) \& \ea alarme (bip) (BEL) \& \ee escape (ESC) \& \e033 caracte\*`re en octal (ESC) \& \ex1B caracte\*`re hexade\*'cimal (ESC) \& \ex{236a} caracte\*`re hexade\*'cimal long (SMILEY) \& \ec[ caracte\*`re de contro\*^le (ESC) \& \eN{nom} caracte\*`re nomme\*' \& \& \el converti en minuscule le caracte\*`re suivant \& \eu converti en majuscule le caracte\*`re suivant \& \eL converti en minuscule jusqu'au prochain \eE \& \eU converti en majuscule jusqu'au prochain \eE \& \eE fin de modification de casse \& \eQ de\*'sactive les me\*'ta\-caracte\*`res de motif jusqu'au prochain \eE .Ve .PP Si \f(CW\*(C`use locale\*(C'\fR est actif, la table de majuscules/minuscules utilise\*'e par \&\f(CW\*(C`\el\*(C'\fR, \f(CW\*(C`\eL\*(C'\fR, \f(CW\*(C`\eu\*(C'\fR et \f(CW\*(C`\eU\*(C'\fR est celle du locale courant. Voir perllocale. Pour la documentation de \f(CW\*(C`\eN{nom}\*(C'\fR, voir charnames. .PP Tous les syste\*`mes utilisent le \f(CW"\en"\fR virtuel pour repre\*'senter une terminaison de ligne appele\*'e \*(L"newline\*(R" ou \*(L"nouvelle ligne\*(R". Il n'existe pas de caracte\*`re physique invariant pour repre\*'senter ce caracte\*`re \*(L"newline\*(R". C'est une illusion qu'essayent conjointement de maintenir le syste\*`me d'exploitation, les pilotes de pe\*'riphe\*'riques, la bibliothe\*`que C et Perl. Tous les syste\*`mes ne lisent pas \f(CW"\er"\fR comme le \s-1CR\s0 \s-1ASCII\s0 ni \f(CW"\en"\fR comme le \s-1LF\s0 \s-1ASCII\s0. Par exemple, sur Mac, ils sont inverse\*'s et sur des syste\*`mes sans terminaison de ligne, e\*'crire \f(CW"\en"\fR peut ne produire aucun donne\*'e. En ge\*'ne\*'ral, utilisez \&\f(CW"\en"\fR lorsque vous pensez \*(L"newline\*(R" pour votre syste\*`me mais utilisez le litte\*'ral \s-1ASCII\s0 quand voulez un caracte\*`re exact. Par exemple, de nombreux protocoles re\*'seaux attendent et pre\*'fe\*`rent un \s-1CR+LF\s0 ((\f(CW"\e012\e015"\fR ou \&\f(CW"\ecJ\ecM"\fR) comme terminaison de ligne. La plupart acceptent juste \f(CW"\e012"\fR et tole\*`re rarement juste \f(CW"\e015"\fR. Si vous prenez l'habitude d'utiliser \&\f(CW"\en"\fR sur les re\*'seaux, vous aurez des proble\*`mes un jour. .PP Vous ne pouvez pas inclure litte\*'ralement les caracte\*`res \f(CW\*(C`$\*(C'\fR et \f(CW\*(C`@\*(C'\fR a\*` l'inte\*'rieur d'une se\*'quence \f(CW\*(C`\eQ\*(C'\fR. Tels quels, ils se re\*'fe\*'reraient a\*` la variable correspondante. Pre\*'ce\*'de\*'s d'un \f(CW\*(C`\e\*(C'\fR, ils correspondraient a\*` la chai\*^ne \&\f(CW\*(C`\e$\*(C'\fR ou \f(CW\*(C`\e@\*(C'\fR. Vous e\*^tes oblige\*'s d'e\*'crire quelque chose comme \&\f(CW\*(C`m/\eQuser\eE\e@\eQhost/\*(C'\fR. .PP Les motifs sont sujets a\*` un niveau supple\*'mentaire d'interpre\*'tation en tant qu'expression rationnelle. C'est fait lors d'une seconde passe apre\*`s l'interpolation des variables si bien qu'une expression rationnelle peut\-e\*^tre introduite dans un motif via une variable. Si ce n'est pas ce que vous voulez, utilisez \f(CW\*(C`\eQ\*(C'\fR pour interpoler une variable litte\*'ralement. .PP Mis a\*` part ce qui pre\*'ce\*`de, il n'y pas de multiples niveaux d'interpolation. En particulier et contrairement a\*` ce qu'attendraient des programmeurs shell, les accents graves (ou backticks) \fI\s-1NE\s0\fR sont \fI\s-1PAS\s0\fR interpole\*'es a\*` l'inte\*'rieur des guillemets et les apostrophes n'empe\*^chent pas l'e\*'valuation des variables a\*` l'inte\*'rieur des guillemets. .Sh "Ope\*'rateurs d'expression rationnelle" .IX Subsection "Ope'rateurs d'expression rationnelle" Nous discuterons ici des ope\*'rateurs style apostrophe qui implique une reconnaissance de motif ou une action s'y rapportant. .IP "?MOTIF?" 8 .IX Item "?MOTIF?" C'est la me\*^me chose qu'une recherche par \f(CW\*(C`/motif/\*(C'\fR sauf qu'elle n'est reconnue qu'une seule fois entre chaque appel a\*` l'ope\*'rateur \fIreset()\fR. C'est une optimisation pratique si vous ne recherchez que la premie\*`re occurrence de quelque chose dans chaque fichier ou groupes de fichiers par exemple. Seuls les motifs \f(CW\*(C`??\*(C'\fR locaux au package courant sont re\*'initialise\*'s par \fIreset()\fR. .Sp .Vb 7 \& while (<>) { \& if (?^$?) { \& # ligne blanche entre en\-te\*^te et corps \& } \& } continue { \& reset if eof; # re\*'initialisation de ?? pour le fichier suivant \& } .Ve .Sp Cet usage est vaguement de\*'sapprouve\*' et peut e\*^tre supprime\*' dans une version future de Perl. Peut\-e\*^tre vers l'anne\*'e 2168. .IP "m/MOTIF/cgimosx" 8 .IX Item "m/MOTIF/cgimosx" .PD 0 .IP "/MOTIF/cgimosx" 8 .IX Item "/MOTIF/cgimosx" .PD Effectue le recherche d'un motif d'expression rationnelle dans une chai\*^ne et, dans un contexte scalaire, renvoie vrai en cas de succe\*`s ou faux sinon. Si aucune chai\*^ne n'est spe\*'cifie\*'e via l'ope\*'rateur \f(CW\*(C`=~\*(C'\fR ou l'ope\*'rateur \f(CW\*(C`!~\*(C'\fR, c'est dans la chai\*^ne \f(CW$_\fR que s'effectue la recherche. (La chai\*^ne spe\*'cifie\*'e par \&\f(CW\*(C`=~\*(C'\fR n'est pas ne\*'cessairement une lvalue \*(-- cela peut e\*^tre le re\*'sultat de l'e\*'valuation d'une expression.) Voir aussi perlre. Voir perllocale pour des informations supple\*'mentaires qui s'appliquent lors de l'usage de \f(CW\*(C`use locale\*(C'\fR. .Sp Les options (ou modificateurs) sont\ : .Sp .Vb 7 \& c Ne pas re\*'initialiser la position de recherche lors d'un e\*'chec avec /g. \& g Recherche globale, i.e. trouver toutes les occurrences. \& i Reconnaissance de motif inde\*'pendamment de la casse (majuscules/minuscules). \& m Traitement de chai\*^ne comme e\*'tant multi\-lignes. \& o Compilation du motif uniquement la premie\*`re fois. \& s Traitement de la chai\*^ne comme e\*'tant une seule ligne. \& x Utilisation des expressions rationnelles e\*'tendues. .Ve .Sp Si \*(L"/\*(R" est le de\*'limiteur alors le \f(CW\*(C`m\*(C'\fR initial est optionnel. Avec le \f(CW\*(C`m\*(C'\fR vous pouvez utiliser n'importe quelle paire de caracte\*`res ni alphanume\*'riques ni blancs comme de\*'limiteur. C'est particulie\*`rement pratique pour les chemins d'acce\*`s Unix qui contiennent des \*(L"/\*(R" afin d'e\*'viter le \s-1LTS\s0 (leaning toothpick syndrome). Si \*(L"?\*(R" est le de\*'limiteur alors la re\*`gle \*(L"ne\-marche\-qu\-une\-fois\*(R" de \&\f(CW\*(C`?MOTIF?\*(C'\fR s'applique. Si \*(L"'\*(R" est le de\*'limiteur alors aucune interpolation n'est effectue\*'e sur le \s-1MOTIF\s0. .Sp \&\s-1MOTIF\s0 peut contenir des variables qui seront interpole\*'es (et le motif recompile\*') chaque fois que la recherche du motif est effectue\*'e sauf si le de\*'limiteur choisi est une apostrophe. (Remarquez que \f(CW$)\fR et \f(CW$|\fR ne peuvent pas e\*^tre interpole\*'s puisqu'ils ressemblent a\*` des tests de fin de chai\*^ne.) Si vous voulez qu'un motif ne soit compile\*' qu'une seule fois, ajoutez \f(CW\*(C`/o\*(C'\fR apre\*`s le dernier de\*'limiteur. Ceci e\*'vite des cou\*^teuses recompilations lors de l'exe\*'cution et c'est utile lorsque le valeur interpole\*'e ne doit pas changer pendant la dure\*'e de vie du script. Par contre, ajouter \f(CW\*(C`/o\*(C'\fR suppose que vous ne changerez pas la valeur des variables pre\*'sentes dans le motif. Si vous les changez, Perl ne s'en apercevra me\*^me pas. Voir aussi \*(L"/\*(R"\*(L" in \*(R"qr. .Sp Si l'e\*'valuation du \s-1MOTIF\s0 est la chai\*^ne vide, la dernie\*`re expression rationnelle \fIreconnue\fR est utilise\*'e a\*` la place. .Sp Si l'option \f(CW\*(C`/g\*(C'\fR n'est pas utilise\*'e, dans un contexte de liste, \f(CW\*(C`m//\*(C'\fR retourne une liste constitue\*'e de tous les sous-motifs reconnus par des parenthe\*`ses dans le motif, i.e. (\f(CW$1\fR, \f(CW$2\fR, \f(CW$3\fR...). (Remarquez que \&\f(CW$1\fR, \f(CW$2\fR, etc. sont aussi mises a\*` jours ce qui diffe\*`re du comportement de Perl 4.) Lorsqu'il n'y a pas de parenthe\*`ses dans le motif, la valeur retourne\*'e est la liste \f(CW\*(C`(1)\*(C'\fR en cas de succe\*`s. Qu'il y ait ou non de parenthe\*`ses, une liste vide est retourne\*'e en cas d'e\*'chec. .Sp Exemples\ : .Sp .Vb 2 \& open(TTY, '/dev/tty'); \& =~ /^y/i && foo(); # appel de foo si de\*'sire\*' \& \& if (/Version: *([0\-9.]*)/) { $version = $1; } \& \& next if m#^/usr/spool/uucp#; \& \& # le grep du pauvre \& $arg = shift; \& while (<>) { \& print if /$arg/o; # compile une seule fois \& } \& \& if (($F1, $F2, $Etc) = ($foo =~ /^(\eS+)\es+(\eS+)\es*(.*)/)) .Ve .Sp Ce dernier exemple de\*'coupe \f(CW$foo\fR en trois parties (le deux premiers mots et le reste de la ligne) et les affecte a\*` \f(CW$F1\fR, \f(CW$F2\fR et \f(CW$Etc\fR. La condition est vraie si au moins une des variables est affecte\*'e, i.e. si le motif est reconnu. .Sp Le modificateur \f(CW\*(C`/g\*(C'\fR spe\*'cifie une recherche globale du motif \*(-- c'est a\*` dire la recherche d'autant de correspondances que possible dans la chai\*^ne. Le comportement de\*'pend du contexte. Dans un contexte de liste, c'est la liste de toutes les sous\-chai\*^nes reconnues par les sous-motifs (entre parenthe\*`ses) du motif qui est retourne\*'e. En l'absence de parenthe\*`ses, c'est la liste de toutes les chai\*^nes correspondant au motif qui est retourne\*'e, comme si il y avait des parenthe\*`ses autour du motif lui\-me\*^me. .Sp Dans un contexte scalaire, chaque exe\*'cution de \f(CW\*(C`m//g\*(C'\fR trouve la prochaine correspondance et retourne vrai si il y a correspondance et faux si il n'y en a plus. La position apre\*`s la dernie\*`re correspondance peut\-e\*^tre lue et modifie\*'e par la fonction \fIpos()\fR; voir \*(L"pos\*(R" in perlfunc. Normalement, un e\*'chec de la recherche re\*'initialise la position de recherche au de\*'but de la chai\*^ne sauf si vous ajoutez le modificateur \f(CW\*(C`/c\*(C'\fR (e.g. \f(CW\*(C`m//gc\*(C'\fR). La modification de la chai\*^ne sur laquelle a\*` lieu la recherche re\*'initialise aussi la position de recherche. .Sp Vous pouvez me\*'langer des reconnaissances \f(CW\*(C`m//g\*(C'\fR avec des \f(CW\*(C`m/\eG.../g\*(C'\fR ou\*` \&\f(CW\*(C`\eG\*(C'\fR est l'assertion de longueur nulle qui est reconnue a\*` la position exacte ou\*`, si elle existe, s'est arre\*^te\*'e la pre\*'ce\*'dente recherche \f(CW\*(C`m//g\*(C'\fR. L'assertion \&\f(CW\*(C`\eG\*(C'\fR n'est pas acceptable sans le modificateur \f(CW\*(C`/g\*(C'\fR. (Dans la version courante, en l'absence de \f(CW\*(C`/g\*(C'\fR, il se trouve que \f(CW\*(C`\eG\*(C'\fR se comporte exactement comme \f(CW\*(C`\eA\*(C'\fR mais c'est accidentel et cela peut changer dans les versions futures.) .Sp Exemples\ : .Sp .Vb 2 \& # contexte de liste \& ($one,$five,$fifteen) = (`uptime` =~ /(\ed+\e.\ed+)/g); \& \& # contexte scalaire \& { \& local $/ = ""; \& while (defined($paragraph = <>)) { \& while ($paragraph =~ /[a\-z]['")]*[.!?]+['")]*\es/g) { \& $sentences++; \& } \& } \& } \& print "$sentences\en"; \& \& # utilisation de m//gc avec \eG \& $_ = "ppooqppqq"; \& while ($i++ < 2) { \& print "1: '"; \& print $1 while /(o)/gc; print "', pos=", pos, "\en"; \& print "2: '"; \& print $1 if /\eG(q)/gc; print "', pos=", pos, "\en"; \& print "3: '"; \& print $1 while /(p)/gc; print "', pos=", pos, "\en"; \& } .Ve .Sp Le dernier exemple devrait afficher\ : .Sp .Vb 6 \& 1: 'oo', pos=4 \& 2: 'q', pos=5 \& 3: 'pp', pos=7 \& 1: '', pos=7 \& 2: 'q', pos=8 \& 3: '', pos=8 .Ve .Sp Une construction idiomatique pratique pour des analyseurs a\*` la \f(CW\*(C`lex\*(C'\fR est \&\f(CW\*(C`/\eG.../gc\*(C'\fR. Vous pouvez combiner plusieurs expressions rationnelles de ce type pour traiter une chai\*^ne partie par partie en faisant diffe\*'rentes actions selon l'expression qui est reconnue. Chaque expression essaye de correspondre la\*` ou\*` la pre\*'ce\*'dente s'est arre\*^te\*'e. .Sp .Vb 10 \& $_ = <<'EOL'; \& $url = new URI::URL "http://www/"; die if $url eq "xXx"; \& EOL \& LOOP: \& { \& print(" chiffres"), redo LOOP if /\eG\ed+\eb[,.;]?\es*/gc; \& print(" minuscule"), redo LOOP if /\eG[a\-z]+\eb[,.;]?\es*/gc; \& print(" MAJUSCULE"), redo LOOP if /\eG[A\-Z]+\eb[,.;]?\es*/gc; \& print(" Capitalise\*'"), redo LOOP if /\eG[A\-Z][a\-z]+\eb[,.;]?\es*/gc; \& print(" MiXtE"), redo LOOP if /\eG[A\-Za\-z]+\eb[,.;]?\es*/gc; \& print(" alphanume\*'rique"), redo LOOP if /\eG[A\-Za\-z0\-9]+\eb[,.;]?\es*/gc; \& print(" autres"), redo LOOP if /\eG[^A\-Za\-z0\-9]+/gc; \& print ". C'est tout !\en"; \& } .Ve .Sp Voici la sortie (de\*'coupe\*'e en plusieurs lignes) : .Sp .Vb 4 \& autres minuscule autres minuscule MAJUSCULE autres \& MAJUSCULE autres minuscule autres minuscule autres \& minuscule minuscule autres minuscule minuscule autres \& MiXtE autres. C'est tout ! .Ve .IP "q/CHAINE/" 8 .IX Item "q/CHAINE/" .PD 0 .IP "'\s-1CHAINE\s0'" 8 .IX Item "'CHAINE'" .PD Une apostrophe pour une chai\*^ne litte\*'rale. Un backslash (une barre oblique inverse) repre\*'sente un backslash sauf si il est suivi par le de\*'limiteur ou par un autre backslash auquel cas le de\*'limiteur ou le backslash est interpole\*'. .Sp .Vb 3 \& $foo = q!I said, "You said, 'She said it.'"!; \& $bar = q('This is it.'); \& $baz = '\en'; # une chai\*^ne de deux caracte\*`res .Ve .IP "qq/CHAINE/" 8 .IX Item "qq/CHAINE/" .PD 0 .ie n .IP """\s-1CHAINE\s0""" 8 .el .IP "``\s-1CHAINE\s0''" 8 .IX Item "CHAINE" .PD Des guillemets pour une chai\*^ne interpole\*'e. .Sp .Vb 4 \& $_ .= qq \& (*** La ligne pre\*'ce\*'dente contient le gros mot "$1".\en) \& if /\eb(tcl|java|python)\eb/i; # :\-) \& $baz = "\en"; # une chai\*^ne d'un caracte\*`re .Ve .IP "qr/CHAINE/imosx" 8 .IX Item "qr/CHAINE/imosx" Ope\*'rateur \*(L"comme\-une\-expression\-regulie\*`re\*(R". \fI\s-1CHAINE\s0\fR est interpole\*'e de la me\*^me manie\*`re que \fI\s-1MOTIF\s0\fR dans \f(CW\*(C`m/MOTIF/\*(C'\fR. Si \*(L"'\*(R" est utilise\*' comme de\*'limiteur, aucune interpolation de variables n'est effectue\*'e. Renvoie une expression Perl qui peut e\*^tre utilise\*'e a\*` la place de l'expression \&\f(CW\*(C`/CHAINE/imosx\*(C'\fR. .Sp Par exemple\ : .Sp .Vb 2 \& $rex = qr/ma.CHAINE/is; \& s/$rex/foo/; .Ve .Sp est e\*'quivalent a\*`\ : .Sp .Vb 1 \& s/ma.CHAINE/foo/is; .Ve .Sp Le re\*'sultat peut e\*^tre utilise\*' comme motif dans une recherche de correspondance\ : .Sp .Vb 4 \& $re = qr/$motif/; \& $string =~ /foo${re}bar/; # peut e\*^tre interpole\*'e dans d'autres motifs \& $string =~ $re; # ou utilise\*'e seule \& $string =~ /$re/; # ou de cette manie\*`re .Ve .Sp Puisque Perl peut compiler le motif lors de l'exe\*'cution de l'ope\*'rateur \fIqr()\fR, l'utilisation de \fIqr()\fR peut augmenter les performances dans quelques situations, notamment si le re\*'sultat de \fIqr()\fR est utilise\*' seul\ : .Sp .Vb 11 \& sub match { \& my $patterns = shift; \& my @compiled = map qr/$_/i, @$patterns; \& grep { \& my $success = 0; \& foreach my $pat @compiled { \& $success = 1, last if /$pat/; \& } \& $success; \& } @_; \& } .Ve .Sp La pre\*'compilation du motif en une repre\*'sentation interne lors du \fIqr()\fR e\*'vite une recompilation a\*` chaque fois qu'une recherche \f(CW\*(C`/$pat/\*(C'\fR est tente\*'e. (Notez que Perl a de nombreuses autres optimisations internes mais aucune n'est de\*'clenche\*'e dans l'exemple pre\*'ce\*'dent si nous n'utilisons pas l'ope\*'rateur \fIqr()\fR.) .Sp Les options sont\ : .Sp .Vb 5 \& i Motif inde\*'pendant de la casse (majuscules/minuscules). \& m Traitement de chai\*^ne comme e\*'tant multi\-lignes. \& o Compilation du motif uniquement la premie\*`re fois. \& s Traitement de la chai\*^ne comme e\*'tant une seule ligne. \& x Utilisation des expressions rationnelles e\*'tendues. .Ve .Sp Voir perlre pour de plus amples informations sur la syntaxe correcte de \&\s-1CHAINE\s0 et pour une description de\*'taille\*'e de la se\*'mantique des expressions rationnelles. .IP "qx/CHAINE/" 8 .IX Item "qx/CHAINE/" .PD 0 .IP "`CHAINE`" 8 .IX Item "`CHAINE`" .PD Une chai\*^ne qui est (e\*'ventuellement) interpole\*'e puis exe\*'cute\*'e comme une commande syste\*`me par \f(CW\*(C`/bin/sh\*(C'\fR ou e\*'quivalent. Les jokers, tubes (pipes) et redirections sont pris en compte. L'ensemble de la sortie standard de la commande est renvoye\*' ; la sortie d'erreur n'est pas affecte\*'e. Dans un contexte scalaire, le re\*'sultat est retourne\*' comme une seule chai\*^ne (potentiellement multi\-lignes). Dans un contexte de liste, le re\*'sultat est une liste de lignes (selon la de\*'finition des lignes donne\*'e par $/ ou \f(CW$INPUT_RECORD_SEPARATOR\fR). .Sp Puisque les apostrophes inverses (backticks) n'affectent pas la sortie d'erreur, il vous faut utiliser la (les) syntaxe(s) de redirection du shell (en supposant qu'elle(s) existe(nt)) afin de capter les erreurs. Pour re\*'cupe\*'rer les sorties \s-1STDOUT\s0 et \s-1STDERR\s0 d'une commande\ : .Sp .Vb 1 \& $output = `cmd 2>&1`; .Ve .Sp Pour re\*'cupe\*'rer \s-1STDOUT\s0 et faire disparai\*^tre \s-1STDERR\s0\ : .Sp .Vb 1 \& $output = `cmd 2>/dev/null`; .Ve .Sp Pour re\*'cupe\*'rer \s-1STDERR\s0 et faire disparai\*^tre \s-1STDOUT\s0 (l'ordre est ici tre\*`s important)\ : .Sp .Vb 1 \& $output = `cmd 2>&1 1>/dev/null`; .Ve .Sp Pour e\*'changer \s-1STDOUT\s0 et \s-1STDERR\s0 afin de re\*'cupe\*'rer \s-1STDERR\s0 tout en laissant \&\s-1STDOUT\s0 s'afficher normalement\ : .Sp .Vb 1 \& $output = `cmd 3>&1 1>&2 2>&3 3>&\-`; .Ve .Sp Pour re\*'cupe\*'rer \s-1STDOUT\s0 et \s-1STDERR\s0 se\*'pare\*'ment, il est plus simple et sain de les rediriger se\*'pare\*'ment vers des fichiers qui seront lus lorsque l'exe\*'cution de la commande sera termine\*'e\ : .Sp .Vb 1 \& system("program args 1>/tmp/program.stdout 2>/tmp/program.stderr"); .Ve .Sp L'utilisation de l'apostrophe comme de\*'limiteur prote\*`ge la commande de l'interpolation normalement effectue\*'e par Perl sur les chai\*^nes entre guillemets. La chai\*^ne est passe\*'e tel quelle au shell : .Sp .Vb 2 \& $perl_info = qx(ps $$); # Le $$ de Perl \& $shell_info = qx'ps $$'; # Le $$ du nouveau shell .Ve .Sp Remarquez que la manie\*`re dont la chai\*^ne est e\*'value\*'e est entie\*`rement de\*'pendante de l'interpre\*'teur de commandes de votre syste\*`me. Sur la plupart des plates\-formes, vous aurez a\*` prote\*'ger les me\*'ta\-caracte\*`res du shell si vous voulez qu'ils soient traite\*'s litte\*'ralement. En pratique, c'est difficile a\*` faire, surtout qu'il n'est pas toujours facile de savoir quels caracte\*`res doivent e\*^tre prote\*'ge\*'s. Voir perlsec pour un exemple propre et su\*^re d'utilisation manuelle de \fIfork()\fR et \fIexec()\fR pour e\*'muler proprement l'utilisation des backticks. .Sp Sur certaines plates-formes (particulie\*`rement celles style \s-1DOS\s0) le shell peut ne pas e\*^tre capable de ge\*'rer des commandes multi\-lignes. Dans ce cas, l'usage de passages a\*` la ligne dans la chai\*^ne de commande ne donne pas ce que vous voulez. Vous pouvez e\*'valuez plusieurs commandes sur une seule et me\*^me ligne et les se\*'parant par le caracte\*`re de se\*'paration de commandes si votre shell le supporte (e.g. \f(CW\*(C`;\*(C'\fR pour la plupart des shells Unix; \f(CW\*(C`&\*(C'\fR sur le \f(CW\*(C`cmd\*(C'\fR shell de Windows \s-1NT\s0). .Sp Depuis la version v5.6.0, Perl tente de vider les tampons de tous les fichiers ouverts en e\*'criture avant de lancer la commande mais cela n'est pas supporte\*' sur toutes les plates-formes (voir perlport). Pour e\*^tre plus su\*^r, vous devriez positionne\*' la variable \f(CW$|\fR ($AUTOFLUSH en anglais) ou appele\*' la me\*'thode \f(CW\*(C`autoflush()\*(C'\fR des objets \f(CW\*(C`IO::Handle\*(C'\fR pour chacun des descripteurs ouverts. .Sp N'oubliez pas que certains shells ont quelques restrictions sur la longueur de la ligne de commande. Vous devez vous assurer que votre chai\*^ne n'exce\*`de pas cette limite me\*^me apre\*`s interpolation. Voir les notes spe\*'cifiques a\*` votre plate-forme pour plus de de\*'tails sur votre environnement particulier. .Sp L'utilisation de cet ope\*'rateur peut aboutir a\*` des programmes difficiles a\*` porter puisque les commandes shells appele\*'es varient d'un syste\*`me a\*` l'autre et peuvent parfois ne pas exister du tout. A\*` titre d'exemple, la commande \f(CW\*(C`type\*(C'\fR du shell \s-1POSIX\s0 est tre\*`s diffe\*'rente de la commande \f(CW\*(C`type\*(C'\fR sous \s-1DOS\s0. Cela ne signifie pas qu'il vous faut a\*` tout prix e\*'viter cet ope\*'rateur lorsque c'est le bon moyen de faire ce que vous voulez. Perl a e\*'te\*' conc\*,u pour e\*^tre un \*(L"glue language\*(R"... La seule chose qui compte c'est que vous sachiez ce que vous faites. .Sp Voir \*(L"S\*(R"\*(L" in \*(R"Les ope\*'rateurs d'E pour des plus amples informations. .IP "qw/CHAINE/" 8 .IX Item "qw/CHAINE/" Retourne la liste des mots extraits de \s-1CHAINE\s0 en utilisant les espaces comme de\*'limiteurs de mots. On peut le conside\*'rer comme e\*'quivalent a\*`\ : .Sp .Vb 1 \& split(' ', q/CHAINE/); .Ve .Sp avec comme diffe\*'rence que la liste est ge\*'ne\*'re\*'e lors de la compilation. Donc .Sp .Vb 1 \& qw(foo bar baz) .Ve .Sp est se\*'mantiquement e\*'quivalente a\*` la liste\ : .Sp .Vb 1 \& 'foo', 'bar', 'baz' .Ve .Sp Quelques exemples fre\*'quemment rencontre\*'s\ : .Sp .Vb 2 \& use POSIX qw( setlocale localeconv ) \& @EXPORT = qw( foo bar baz ); .Ve .Sp Une erreur assez commune consiste a\*` se\*'parer les mots par des virgules ou a\*` mettre des commentaires dans une \f(CW\*(C`qw\*(C'\fR\-chai\*^ne multi\-lignes. C'est la raison pour laquelle \f(CW\*(C`use warnings\*(C'\fR ou l'option \f(CW\*(C`\-w\*(C'\fR (c'est a\*` dire la variable \&\f(CW$^W\fR) produit un message d'avertissement lorsque \s-1CHAINE\s0 contient le caracte\*`re \*(L",\*(R" ou le caracte\*`re \*(L"#\*(R". .IP "s/MOTIF/REMPLACEMENT/egimosx" 8 .IX Item "s/MOTIF/REMPLACEMENT/egimosx" Recherche le motif dans une chai\*^ne puis, s'il est trouve\*', le substitue par le texte de \s-1REMPLACEMENT\s0 et retourne finalement le nombre de substitutions effectue\*'es. Sinon, renvoie faux (en l'espe\*`ce, la chai\*^ne vide). .Sp Si aucune chai\*^ne n'est spe\*'cifie\*'e via \f(CW\*(C`=~\*(C'\fR ou \f(CW\*(C`!~\*(C'\fR, la recherche et la substitution s'appliquent a\*` la variable \f(CW$_\fR. (La chai\*^ne spe\*'cifie\*'e par \f(CW\*(C`=~\*(C'\fR doit e\*^tre une variable scalaire, un e\*'le\*'ment d'un tableau ou d'une table de hachage ou une affectation de l'un ou de l'autre... en un mot, une lvalue.) .Sp Si le de\*'limiteur choisi est l'apostrophe, aucune interpolation n'est effectue\*'e ni sur \s-1MOTIF\s0 ni sur \s-1REMPLACEMENT\s0. Sinon, si \s-1MOTIF\s0 contient un $ qui ressemble plus a\*` une variable qu'a\*` un test de fin de chai\*^ne, la variable sera interpole\*'e dans le motif lors de l'exe\*'cution. Si vous voulez que le motif ne soit compile\*' qu'une seule fois la premie\*`re fois que la variable est interpole\*'e, utilisez l'option \f(CW\*(C`/o\*(C'\fR. Si l'e\*'valuation du motif est la chai\*^ne nulle, la dernie\*`re expression rationnelle reconnue est utilise\*'e a\*` la place. Voir perlre pour de plus amples informations a\*` ce sujet. Voir perllocale pour des informations supple\*'mentaires qui s'appliquent lors de l'usage de \f(CW\*(C`use locale\*(C'\fR. .Sp Les options sont\ : .Sp .Vb 7 \& e E\*'valuez la partie droite comme une expression. \& g Substitution globale, i.e. toutes les occurrences. \& i Motif inde\*'pendant de la casse (majuscules/minuscules). \& m Traitement de chai\*^ne comme e\*'tant multi\-lignes. \& o Compilation du motif uniquement la premie\*`re fois. \& s Traitement de la chai\*^ne comme e\*'tant une seule ligne. \& x Utilisation des expressions rationnelles e\*'tendues. .Ve .Sp N'importe quel de\*'limiteur (ni blanc ni alphanume\*'rique) peut remplacer les barres obliques (slash). Si l'apostrophe est utilise\*'e, aucune interpolation n'est effectue\*'e sur la chai\*^ne de remplacement (par contre, le modificateur \&\f(CW\*(C`/e\*(C'\fR passe outre). Au contraire de Perl 4, Perl 5 conside\*`re l'accent grave (backtick) comme un de\*'limiteur normal ; le texte de remplacement n'est pas e\*'value\*' comme une commande. Si le \s-1MOTIF\s0 est de\*'limite\*' par des caracte\*`res fonctionnant en paire (comme les parenthe\*`ses), le texte de \s-1REMPLACEMENT\s0 a sa propre paire de de\*'limiteurs qui peuvent e\*^tre ou non des caracte\*`res fonctionnant par paire, e.g. \f(CW\*(C`s(foo)(bar)\*(C'\fR ou \&\f(CW\*(C`s/bar/\*(C'\fR. L'option \f(CW\*(C`/e\*(C'\fR implique que la partie remplacement sera interpre\*'te\*'e comme une expression Perl a\*` part entie\*`re et donc e\*'value\*'e comme telle. Par contre, sa validite\*' syntaxique est e\*'value\*'e lors de la compilation. Un seconde option \f(CW\*(C`e\*(C'\fR provoquera l'e\*'valuation de la partie \&\s-1REMPLACEMENT\s0 avant son exe\*'cution en tant qu'expression Perl. .Sp Exemples:\ .Sp .Vb 1 \& s/\ebgreen\eb/mauve/g; # ne modifie pas wintergreen \& \& $path =~ s|/usr/bin|/usr/local/bin|; \& \& s/Login: $foo/Login: $bar/; # motif dynamique \& \& ($foo = $bar) =~ s/this/that/; # recopie puis modification \& \& $count = ($paragraph =~ s/Mister\eb/Mr./g); # calcul du nombre de substitution \& \& $_ = 'abc123xyz'; \& s/\ed+/$&*2/e; # produit 'abc246xyz' \& s/\ed+/sprintf("%5d",$&)/e; # produit 'abc 246xyz' \& s/\ew/$& x 2/eg; # produit 'aabbcc 224466xxyyzz' \& \& s/%(.)/$percent{$1}/g; # pas de /e \& s/%(.)/$percent{$1} || $&/ge; # une expression donc /e \& s/^=(\ew+)/&pod($1)/ge; # appel de fonction \& \& # expansion des variables dans $_, mais dynamique uniquement \& # en utilisant le de\*'re\*'fe\*'rencement symbolique \& s/\e$(\ew+)/${$1}/g; \& \& # Ajoute un a\*` chaque nombre pre\*'sent dans la chai\*^ne \& s/(\ed+)/1 + $1/eg; \& \& # Ceci de\*'veloppe toutes les variables scalaires incluses \& # (me\*^me les lexicales) dans $_ : $1 est tout d'abord interpole\*' \& # puis e\*'value\*' \& s/(\e$\ew+)/$1/eeg; \& \& # Suppression des commentaires C (presque tous). \& $program =~ s { \& /\e* # Reconnais le de\*'but du commentaire \& .*? # Reconnais un minimum de caracte\*`res \& \e*/ # Reconnais la fin de commentaire \& } []gsx; \& \& s/^\es*(.*?)\es*$/$1/; # suppression des espaces aux extre\*'mite\*'s de $_ (couteux) \& \& for ($variable) { # suppression des espaces aux extre\*'mite\*'s de $variable (efficace) \& s/^\es+//; \& s/\es+$//; \& } \& \& s/([^ ]*) *([^ ]*)/$2 $1/; # inverse les deux premiers champs .Ve .Sp Remarquez l'usage de $ a\*` la place de \e dans le dernier exemple. A\*` l'inverse de \&\fBsed\fR, nous utilisons la forme \e<\fIdigit\fR> uniquement dans la partie gauche. Partout ailleurs, c'est $<\fIdigit\fR>. .Sp Dans certains cas, il ne suffit pas de mettre \f(CW\*(C`/g\*(C'\fR pour modifier toutes les occurrences. Voici quelques cas communs : .Sp .Vb 4 \& # placer des virgules correctement dans un entier \& # (NdT: en franc\*,ais, on mettrait des espaces) \& 1 while s/(.*\ed)(\ed\ed\ed)/$1,$2/g; # perl4 \& 1 while s/(\ed)(\ed\ed\ed)(?!\ed)/$1,$2/g; # perl5 \& \& # remplacement des tabulations par 8 espaces \& 1 while s/\et+/' ' x (length($&)*8 \- length($`)%8)/e; .Ve .IP "tr/LISTERECHERCHEE/LISTEREMPLACEMENT/cds" 8 .IX Item "tr/LISTERECHERCHEE/LISTEREMPLACEMENT/cds" .PD 0 .IP "y/LISTERECHERCHEE/LISTEREMPLACEMENT/cds" 8 .IX Item "y/LISTERECHERCHEE/LISTEREMPLACEMENT/cds" .PD Translitte\*`re chacune des occurrences des caracte\*`res de la liste recherche\*'e par le caracte\*`re correspondant de la liste de remplacement. Cette ope\*'rateur retourne le nombre de caracte\*`res remplace\*'s ou supprime\*'s. Si aucune chai\*^ne n'est spe\*'cifie\*' via =~ ou !~, la translitte\*'ration s'applique a\*` \f(CW$_\fR. (La chai\*^ne spe\*'cifie\*'e par \f(CW\*(C`=~\*(C'\fR doit e\*^tre une variable scalaire, un e\*'le\*'ment d'un tableau ou d'un table de hachage ou une affectation de l'un ou de l'autre... en un mot, une lvalue.) .Sp Un intervalle de caracte\*`res peut\-e\*^tre spe\*'cifie\*' gra\*^ce a\*` un tiret. Donc \&\f(CW\*(C`tr/A\-J/0\-9/\*(C'\fR effectue les me\*^mes translitte\*'rations que \&\f(CW\*(C`tr/ACEGIBDFHJ/0246813579/\*(C'\fR. Pour les adeptes de \fBsed\fR, \f(CW\*(C`y\*(C'\fR est fourni comme un synonyme de \f(CW\*(C`tr\*(C'\fR. Si la liste recherche\*'e est de\*'limite\*'e par des caracte\*`res fonctionnant par paire (comme les parenthe\*`ses) alors la liste de remplacement a ses propres de\*'limiteurs, e.g. \f(CW\*(C`tr[A\-Z][a\-z]\*(C'\fR ou \&\f(CW\*(C`tr(+\e\-*/)/ABCD/\*(C'\fR. .Sp Remarquez aussi que le concept d'intervalle de caracte\*`res n'est pas vraiment portable entre diffe\*'rents codages \*(-- et me\*^me dans un me\*^me codage, cela peut produire un re\*'sultat que vous n'attendez pas. Un bon principe de base est de n'utiliser que des intervalles qui commencent et se terminent dans le me\*^me alphabet ([a\-e], [A\-E]) ou dans les chiffres ([0\-9]). Tout le reste n'est pas su\*^r. Dans le doute, e\*'nume\*'rez l'ensemble des caracte\*`res explicitement. .Sp Les options (ou modificateurs)\ : .Sp .Vb 5 \& c Comple\*'mente la SEARCHLIST. \& d Efface les caracte\*`res trouve\*'s mais non remplace\*'s. \& s Agre\*`ge les caracte\*`res de remplacement duplique\*'s. \& U Transcrit vers/depuis UTF\-8 \& C Transcrit vers/depuis des caracte\*`res 8\-bit (octet). .Ve .Sp Si le modificateur \f(CW\*(C`/c\*(C'\fR est utilise\*', c'est le comple\*'ment de la liste recherche\*'e qui est utilise\*'. Si le modificateur \f(CW\*(C`/d\*(C'\fR est spe\*'cifie\*', tout caracte\*`re spe\*'cifie\*' dans \s-1LISTERECHERCHEE\s0 et sans e\*'quivalent dans \&\s-1LISTEREMPLACEMENT\s0 est efface\*'. (Ceci est tout de me\*^me plus flexible que le comportement de certains programme \fBtr\fR qui efface tout ce qui est dans \&\s-1LISTERECHERCHEE\s0, point!) Si le modificateur \f(CW\*(C`/s\*(C'\fR est spe\*'cifie\*', les suites de caracte\*`res qui sont translitte\*'re\*'s par le me\*^me caracte\*`re sont agre\*'ge\*'es en un seul caracte\*`re. .Sp Si le modificateur \f(CW\*(C`/d\*(C'\fR est utilise\*', \s-1LISTEREMPLACEMENT\s0 est toujours interpre\*'te\*' exactement comme spe\*'cifie\*'. Sinon, si \s-1LISTEREMPLACEMENT\s0 est plus court que \s-1LISTERECHERCHEE\s0, le dernier caracte\*`re est re\*'pe\*'te\*' autant de fois que ne\*'cessaire pour obtenir la me\*^me longueur. Si \s-1LISTEREMPLACEMENT\s0 est vide, \&\s-1LISTERECHERCHEE\s0 est utilise\*' a\*` la place. Ce dernier point est tre\*`s pratique pour comptabiliser les occurrences d'une classe de caracte\*`res ou pour agre\*'ger les suites de caracte\*`res d'une classe. .Sp Le premier modificateur \f(CW\*(C`/U\*(C'\fR ou \f(CW\*(C`/C\*(C'\fR s'applique a\*` la partie gauche de la transcription. Le second s'applique a\*` la parti droite. Lorsqu'ils sont pre\*'sents, ces modificateurs passent outre l'e\*'tat utf8 courant. .Sp Exemples\ : .Sp .Vb 1 \& $ARGV[1] =~ tr/A\-Z/a\-z/; # tout en minuscule \& \& $cnt = tr/*/*/; # compte les e\*'toiles dans $_ \& \& $cnt = $sky =~ tr/*/*/; # compte les e\*'toiles dans $sky \& \& $cnt = tr/0\-9//; # compte les chiffres dans $_ \& \& tr/a\-zA\-Z//s; # bookkeeper \-> bokeper \& \& ($HOST = $host) =~ tr/a\-z/A\-Z/; \& \& tr/a\-zA\-Z/ /cs; # remplace tous les non alphanume\*'riques \& # par un seul espace \& \& tr [\e200\-\e377] \& [\e000\-\e177]; # efface le 8e\*`me bit. \& \& tr/\e0\-\exFF//CU; # change Latin\-1 to Unicode \& tr/\e0\-\ex{FF}//UC; # change Unicode to Latin\-1 .Ve .Sp Si plusieurs caracte\*`res de translitte\*'ration sont donne\*'s pour un caracte\*`re, seul le premier est utilise\*' : .Sp .Vb 1 \& tr/AAA/XYZ/ .Ve .Sp translitte\*'rera tous les A en X. .Sp Remarquez que puisque la table de translitte\*'ration est construite lors de la compilation, ni \s-1LISTERECHERCHEE\s0 ni \s-1LISTEREMPLACEMENT\s0 ne sont sujettes a\*` l'interpolation de chai\*^ne entre guillemets. Cela signifie que si vous voulez utiliser des variables, vous devez utiliser \fIeval()\fR\ : .Sp .Vb 2 \& eval "tr/$oldlist/$newlist/"; \& die $@ if $@; \& \& eval "tr/$oldlist/$newlist/, 1" or die $@; .Ve .Sh "Les de\*'tails sordides de l'interpre\*'tation des chai\*^nes" .IX Subsection "Les de'tails sordides de l'interpre'tation des chai^nes" Face a\*` quelque chose qui pourrait avoir diffe\*'rentes interpre\*'tations, Perl utilise le principe du \fB\s-1FCQJP\s0\fR (qui signifie Fait Ce Que Je Pense) pour choisir l'interpre\*'tation la plus probable. Cette strate\*'gie fonctionne tellement bien que les utilisateurs de Perl soupc\*,onnent rarement l'ambigui\*:te\*' de ce qu'ils e\*'crivent. Par contre, de temps a\*` autre, l'ide\*'e que se fait Perl diffe\*`re de ce que l'auteur du programme pensait. .PP L'objet de cette partie est de clarifier la manie\*`re dont Perl interpre\*`te les chai\*^nes. La raison la plus fre\*'quente pour laquelle quelqu'un a besoin de connai\*^tre tous ces de\*'tails est l'utilisation d'une expression rationnelle \&\*(L"velue\*(R". Par contre, les premiers pas de l'interpre\*'tation d'une chai\*^ne sont les me\*^mes pour toutes les constructions de chai\*^nes. Ils sont donc explique\*'s ensemble. .PP L'e\*'tape la plus importante de l'interpre\*'tation des chai\*^nes dans Perl est la premie\*`re expose\*'e ci-dessous\ : lors d'une interpre\*'tation de chai\*^nes, Perl cherche d'abord la fin de la construction puis il interpre\*`te le contenu de cette construction. Si vous comprenez cette re\*`gle, vous pouvez sauter les autres e\*'tapes en premie\*`re lecture. Contrairement a\*` cette premie\*`re e\*'tape, les autres e\*'tapes contredisent beaucoup moins souvent les attentes de l'utilisateur. .PP Quelques-unes des passes expose\*'es plus loin sont effectue\*'es simultane\*'ment. Mais comme le re\*'sultat est le me\*^me, nous les conside\*'rerons successivement une par une. Selon la construction, Perl effectue ou non certaines passes (de une a\*` cinq) mais elles sont toujours applique\*'es dans le me\*^me ordre. .IP "Trouver la fin" 4 .IX Item "Trouver la fin" La premie\*`re passe consiste a\*` trouver la fin de la construction qui peut e\*^tre la suite de caracte\*`res \f(CW"\enEOF\en"\fR d'une construction \f(CW\*(C`<\*(C'\fR qui termine un fileglob commence\*' par \f(CW\*(C`<\*(C'\fR. .Sp Lors de la recherche d'un caracte\*`re de\*'limiteur non appaire\*' comme \f(CW\*(C`/\*(C'\fR, les combinaisons comme \f(CW\*(C`\e\e\*(C'\fR et \f(CW\*(C`\e/\*(C'\fR sont saute\*'es. Lors de la recherche d'un de\*'limiteur appaire\*' comme \f(CW\*(C`]\*(C'\fR, les combinaisons \f(CW\*(C`\e\e\*(C'\fR, \f(CW\*(C`\e]\*(C'\fR et \f(CW\*(C`\e[\*(C'\fR sont saute\*'es ainsi que les constructions imbrique\*'es \f(CW\*(C`[\*(C'\fR \f(CW\*(C`]\*(C'\fR. Lors de la recherche d'une suite de caracte\*`res, rien n'est omis. .Sp Pour les constructions en trois parties (\f(CW\*(C`s///\*(C'\fR, \f(CW\*(C`y///\*(C'\fR et \f(CW\*(C`tr///\*(C'\fR), la recherche est re\*'pe\*'te\*'e une fois supple\*'mentaire. .Sp Lors de cette recherche, aucune attention n'est accorde\*'e a\*` la se\*'mantique de la construction, donc\ : .Sp .Vb 1 \& "$hash{"$foo/$bar"}" .Ve .Sp ou : .Sp .Vb 3 \& m/ \& bar # Ce n'est PAS un commentaire, ce slash / termine m// ! \& /x .Ve .Sp ne constituent donc pas des constructions le\*'gales. L'expression se termine au premier \f(CW\*(C`"\*(C'\fR ou \f(CW\*(C`/\*(C'\fR et le reste apparai\*^t comme une erreur de syntaxe. Remarquez que puisque le slash qui termine \f(CW\*(C`m//\*(C'\fR est suivi pas un \&\f(CW\*(C`ESPACE\*(C'\fR, ce n'est pas une constructions \f(CW\*(C`m//x\*(C'\fR et donc \f(CW\*(C`#\*(C'\fR est interpre\*'te\*' comme un \f(CW\*(C`#\*(C'\fR litte\*'ral. .IP "Suppression des barres obliques inverses (backslash) pre\*'ce\*'dents les de\*'limiteurs" 4 .IX Item "Suppression des barres obliques inverses (backslash) pre'ce'dents les de'limiteurs" Lors de la seconde passe, le texte entre le de\*'limiteur de de\*'part et le de\*'limiteur de fin est recopie\*' a\*` un endroit su\*^r et le \f(CW\*(C`\e\*(C'\fR des combinaisons constitue\*'es par un \f(CW\*(C`\e\*(C'\fR suivi du de\*'limiteur (ou des de\*'limiteurs si celui de de\*'part diffe\*`re de celui de fin) est supprime\*'. Cette suppression n'a pas lieu pour des de\*'limiteurs multi\-caracte\*`res. .Sp Remarquez que la combinaison \f(CW\*(C`\e\e\*(C'\fR est laisse\*'e telle quelle. .Sp A\*` partir de ce moment plus aucune information concernant le(s) de\*'limiteur(s) n'est utilise\*'e. .IP "Interpolation" 4 .IX Item "Interpolation" L'e\*'tape suivante est l'interpolation applique\*'e au texte isole\*' de ses de\*'limiteurs. Il y a quatre cas diffe\*'rents. .RS 4 .ie n .IP """<<'EOF'""\fR, \f(CW""m''""\fR, \f(CW""s'''""\fR, \f(CW""tr///""\fR, \f(CW""y///""" 4 .el .IP "\f(CW<<'EOF'\fR, \f(CWm''\fR, \f(CWs'''\fR, \f(CWtr///\fR, \f(CWy///\fR" 4 .IX Item "<<'EOF', m'', s''', tr///, y///" Aucune interpolation n'est applique\*'e. .ie n .IP "''\fR, \f(CW""q//""" 4 .el .IP "\f(CW''\fR, \f(CWq//\fR" 4 .IX Item "'', q//" La seule interpolation est la suppression du \f(CW\*(C`\e\*(C'\fR des paires \f(CW\*(C`\e\e\*(C'\fR. .ie n .IP """""\fR, \f(CW``\fR, \f(CW""qq//""\fR, \f(CW""qx//""\fR, \f(CW""""" 4 .el .IP "\f(CW``''\fR, \f(CW``\fR, \f(CWqq//\fR, \f(CWqx//\fR, \f(CW\fR" 4 .IX Item """"", ``, qq//, qx//, " Les \f(CW\*(C`\eQ\*(C'\fR, \f(CW\*(C`\eU\*(C'\fR, \f(CW\*(C`\eu\*(C'\fR, \f(CW\*(C`\eL\*(C'\fR, \f(CW\*(C`\el\*(C'\fR (e\*'ventuellement associe\*' avec \f(CW\*(C`\eE\*(C'\fR) sont transforme\*'s en leur construction Perl correspondante et donc \&\f(CW"$foo\eQbaz$bar"\fR est transforme\*' en \f(CW\*(C`$foo . (quotemeta("baz" . $bar))\*(C'\fR en interne. Les autres combinaisons constitue\*'es d'un \f(CW\*(C`\e\*(C'\fR suivi d'un ou plusieurs caracte\*`res sont remplace\*'es par le ou les caracte\*`res approprie\*'s. .Sp Soyez conscient que \fItout ce qui est entre \f(CI\*(C`\eQ\*(C'\fI et \f(CI\*(C`\eE\*(C'\fI\fR est interpole\*' de manie\*`re classique. Donc \f(CW"\eQ\e\eE"\fR ne contient pas de \f(CW\*(C`\eE\*(C'\fR : il contient \&\f(CW\*(C`\eQ\*(C'\fR, \f(CW\*(C`\e\e\*(C'\fR et \f(CW\*(C`E\*(C'\fR donc le re\*'sultat est le me\*^me que \f(CW"\e\e\e\eE"\fR. Plus ge\*'ne\*'ralement, la pre\*'sence de backslash entre \f(CW\*(C`\eQ\*(C'\fR et \f(CW\*(C`\eE\*(C'\fR aboutit a\*` des re\*'sultats contre\-intuitifs. Donc \f(CW"\eQ\et\eE"\fR est converti en \&\f(CW\*(C`quotemeta("\et")\*(C'\fR qui est la me\*^me chose que \f(CW"\e\e\et"\fR (puisque \s-1TAB\s0 n'est pas alphanume\*'rique). Remarquez aussi que\ : .Sp .Vb 2 \& $str = '\et'; \& return "\eQ$str"; .Ve .Sp est peut\-e\*^tre plus proche de \fIl'intention\fR de celui qui e\*'crit \f(CW"\eQ\et\eE"\fR. .Sp Les scalaires et tableaux interpole\*'s sont convertis en une se\*'rie d'ope\*'rations de concate\*'nation \f(CW\*(C`join\*(C'\fR et \f(CW\*(C`.\*(C'\fR. Donc \f(CW"$foo XXX '@arr'"\fR devient\ : .Sp .Vb 1 \& $foo . " XXX '" . (join $", @arr) . "'"; .Ve .Sp Toutes les e\*'tapes pre\*'ce\*'dentes sont effectue\*'es simultane\*'ment de la gauche vers la droite. .Sp Puisque le re\*'sultat de \f(CW"\eQ STRING \eE"\fR a tous ses me\*'ta\-caracte\*`res quote\*'s, il n'y aucun moyen d'inse\*'rer litte\*'ralement un \f(CW\*(C`$\*(C'\fR ou un \f(CW\*(C`@\*(C'\fR dans une paire \&\f(CW\*(C`\eQ\eE\*(C'\fR\ : si il est prote\*'ge\*' par \f(CW\*(C`\e\*(C'\fR, un \f(CW\*(C`$\*(C'\fR deviendra \*(L"\e\e\e$\*(R" et sinon il sera interpre\*'te\*' comme le de\*'but d'un scalaire a interpole\*'. .Sp Remarquez aussi que l'interpolation de code doit de\*'cider ou\*` se termine un scalaire interpole\*'. Par exemple \f(CW"a $b \-> {c}"\fR peut signifier\ : .Sp .Vb 1 \& "a " . $b . " \-> {c}"; .Ve .Sp ou\ : .Sp .Vb 1 \& "a " . $b \-> {c}; .Ve .Sp Dans la plupart des cas, le choix est de conside\*'rer le texte le plus long possible n'incluant pas d'espaces entre ses composants et contenant des crochets ou accolades bien e\*'quilibre\*'s. Puisque le re\*'sultat peut\-e\*^tre celui d'un vote entre plusieurs estimateurs heuristiques, le re\*'sultat n'est pas strictement pre\*'visible. Heureusement, il est habituellement correct pour les cas ambigus. .ie n .IP """?RE?""\fR, \f(CW""/RE/""\fR, \f(CW""m/RE/""\fR, \f(CW""s/RE/foo/""," 4 .el .IP "\f(CW?RE?\fR, \f(CW/RE/\fR, \f(CWm/RE/\fR, \f(CWs/RE/foo/\fR," 4 .IX Item "?RE?, /RE/, m/RE/, s/RE/foo/," Le traitement des \f(CW\*(C`\eQ\*(C'\fR, \f(CW\*(C`\eU\*(C'\fR, \f(CW\*(C`\eu\*(C'\fR, \f(CW\*(C`\eL\*(C'\fR, \f(CW\*(C`\el\*(C'\fR et des interpolations est effectue\*' quasiment de la me\*^me manie\*`re qu'avec les constructions \f(CW\*(C`qq//\*(C'\fR sauf que la substitution d'un \f(CW\*(C`\e\*(C'\fR suivi d'un ou plusieurs caracte\*`res spe\*'ciaux pour les expressions rationnelles (incluant \f(CW\*(C`\e\*(C'\fR) n'a pas lieu. En outre, dans les constructions \f(CW\*(C`(?{BLOC})\*(C'\fR, \f(CW\*(C`(?# comment )\*(C'\fR, et \f(CW\*(C`#\*(C'\fR\-comment pre\*'sentes dans les expressions rationnelles \f(CW\*(C`//x\*(C'\fR, aucun traitement n'est effectue\*'. C'est le premier cas ou la pre\*'sence de l'option \f(CW\*(C`//x\*(C'\fR est significative. .Sp L'interpolation a quelques \f(CW\*(C`bizarreries :\*(C'\fR \f(CW$|\fR, \f(CW$(\fR et \f(CW$)\fR ne sont pas interpole\*'s et les constructions comme \f(CW$var[QQCH]\fR peuvent e\*^tre vues (selon le vote de plusieurs estimateurs diffe\*'rents) soit comme un e\*'le\*'ment d'un tableau soit comme \f(CW$var\fR suivi par une alternative \s-1RE\s0. C'est la\*` ou\*` la notation \f(CW\*(C`${arr[$bar]}\*(C'\fR prend tout sons inte\*'re\*^t : \f(CW\*(C`/${arr[0\-9]}/\*(C'\fR est interpre\*'te\*' comme l'e\*'le\*'ment \f(CW\*(C`\-9\*(C'\fR du tableau et pas comme l'expression rationnelle contenu dans \f(CW$arr\fR suivie d'un chiffre (qui est l'interpre\*'tation de \f(CW\*(C`/$arr[0\-9]/\*(C'\fR). Puisqu'un vote entre diffe\*'rents estimateurs peut avoir lieu, le re\*'sultat n'est pas pre\*'visible. .Sp C'est a\*` ce moment que la construction \f(CW\*(C`\e1\*(C'\fR est convertie en \f(CW$1\fR dans le texte de remplacement de \f(CW\*(C`s///\*(C'\fR pour corriger les incorrigibles adeptes de \&\fIsed\fR qui n'ont pas encore compris l'idiome. Un avertissement est e\*'mis si le pragma \f(CW\*(C`use warnings\*(C'\fR ou l'option \fB\-w\fR (c'est a\*` dire la variable \f(CW$^W\fR) est actif. .Sp Remarquez que l'absence de traitement de \f(CW\*(C`\e\e\*(C'\fR cre\*'e des restrictions spe\*'cifiques sur le texte apre\*`s traitement\ : si le de\*'limiteur est \f(CW\*(C`/\*(C'\fR, on ne peut pas obtenir \f(CW\*(C`\e/\*(C'\fR comme re\*'sultat de cette e\*'tape (\f(CW\*(C`/\*(C'\fR finirait l'expression rationnelle, \f(CW\*(C`\e/\*(C'\fR serait transforme\*' en \f(CW\*(C`/\*(C'\fR par l'e\*'tape pre\*'ce\*'dente et \f(CW\*(C`\e\e/\*(C'\fR serait laisse\*' tel quel). Puisque \f(CW\*(C`/\*(C'\fR est e\*'quivalent a\*` \&\f(CW\*(C`\e/\*(C'\fR dans une expression rationnelle, ceci ne pose proble\*`me que lorsque le de\*'limiteur est un caracte\*`re spe\*'cial pour le moteur \s-1RE\s0 comme dans \&\f(CW\*(C`s*foo*bar*\*(C'\fR, \f(CW\*(C`m[foo]\*(C'\fR, ou \f(CW\*(C`?foo?\*(C'\fR ou si le de\*'limiteur est un caracte\*`re alphanume\*'rique comme dans\ : .Sp .Vb 1 \& m m ^ a \es* b mmx; .Ve .Sp Dans l'expression rationnelle ci-dessus qui est volontairement obscure pour l'exemple, le de\*'limiteur est \f(CW\*(C`m\*(C'\fR, le modificateur est \f(CW\*(C`mx\*(C'\fR et apre\*`s la suppression des backslash, l'expression est la me\*^me que \f(CW\*(C`m/ ^ a s* b /mx\*(C'\fR. Il y a de nombreuses raisons de vous encourager a\*` ne choisir que des caracte\*`res non alphanume\*'riques et non blancs comme se\*'parateur. .RE .RS 4 .Sp Cette e\*'tape est la dernie\*`re pour toutes les constructions sauf pour les expressions rationnelles qui sont traite\*'es comme de\*'crit ci\-apre\*`s. .RE .IP "Interpolation des expressions rationnelles" 4 .IX Item "Interpolation des expressions rationnelles" Toutes les e\*'tapes pre\*'ce\*'dentes sont effectue\*'es lors de la compilation du code Perl alors que celle que nous de\*'crivons ici l'est a priori lors de l'exe\*'cution (bien qu'elle soit parfois effectue\*'e lors de la compilation pour des raisons d'optimisation). Apre\*`s tous les pre\*'\-traitements pre\*'ce\*'dents (et e\*'valuation des e\*'ventuels concate\*'nations, jointures, changements de casse et applications de \&\f(CW\*(C`quotemeta()\*(C'\fR de\*'duits), la \fIchai\*^ne\fR re\*'sultante est transmise au moteur \s-1RE\s0 pour compilation. .Sp Ce qui se passe a\*` l'inte\*'rieur du moteur \s-1RE\s0 est bien mieux explique\*' dans perlre mais dans un souci de continuite\*', nous l'exposons un peu ici. .Sp Voici donc une autre e\*'tape ou\*` la pre\*'sence du modificateur \f(CW\*(C`//x\*(C'\fR est prise en compte. Le moteur \s-1RE\s0 explore la chai\*^ne de gauche a\*` droite et la convertit en un automate a\*` e\*'tats finis. .Sp Les caracte\*`res \*(L"backslashe\*'s\*(R" sont alors remplace\*'s par la chai\*^ne correspondante (comme pour \f(CW\*(C`\e{\*(C'\fR) ou ge\*'ne\*`rent des noeuds spe\*'ciaux dans l'automate a\*` e\*'tats finis (comme pour \f(CW\*(C`\eb\*(C'\fR). Les caracte\*`res ayant un sens spe\*'cial pour le moteur \&\s-1RE\s0 (comme \f(CW\*(C`|\*(C'\fR) ge\*'ne\*`rent les noeuds ou les groupes de noeuds correspondants. Les commentaires \f(CW\*(C`(?#...)\*(C'\fR sont ignore\*'s. Tout le reste est converti en chai\*^ne litte\*'rale a\*` reconnai\*^tre ou est ignore\*' (par exemple les espaces et les commentaires \f(CW\*(C`#\*(C'\fR si le modificateur \f(CW\*(C`//x\*(C'\fR est pre\*'sent). .Sp Remarquez que le traitement de la construction \f(CW\*(C`[...]\*(C'\fR est effectue\*' en utilisant des re\*`gles comple\*`tement diffe\*'rentes du reste de l'expression rationnelle. Le terminateur de cette construction est trouve\*' en utilisant les me\*^mes re\*`gles que celles utilise\*'es pour trouver le terminateur d'une construction de\*'limite\*'e (comme \f(CW\*(C`{}\*(C'\fR). La seule exception est le \f(CW\*(C`]\*(C'\fR qui suit imme\*'diatement le \f(CW\*(C`[\*(C'\fR et qui est conside\*'re\*' comme pre\*'ce\*'de\*' d'un backslash. De manie\*`re similaire, la construction \f(CW\*(C`(?{...})\*(C'\fR n'est explore\*'e que pour ve\*'rifier que les parenthe\*`ses, crochets et autres accolades sont bien e\*'quilibre\*'s. .Sp Il est possible d'inspecter la chai\*^ne envoye\*'e au moteur \s-1RE\s0 ainsi que l'automate a\*` e\*'tats finis re\*'sultant. Voir les arguments \f(CW\*(C`debug\*(C'\fR/\f(CW\*(C`debugcolor\*(C'\fR de la directive \f(CW\*(C`use re\*(C'\fR et/ou l'option Perl \fB\-Dr\fR dans \&\*(L"Options de Ligne de Commande\*(R" in perlrun. .IP "Optimisation des expressions rationnelles" 4 .IX Item "Optimisation des expressions rationnelles" Cette e\*'tape n'est cite\*'e que dans un souci de comple\*'tude. Puisque elle ne change en rien la se\*'mantique, les de\*'tails de cette e\*'tape ne sont pas documente\*'s et sont susceptibles d'e\*'voluer. Cette e\*'tape est applique\*'e a\*` l'automate a\*` e\*'tats finis ge\*'ne\*'re\*' lors des e\*'tapes pre\*'ce\*'dentes. .Sp C'est lors de cette e\*'tape que \f(CW\*(C`split()\*(C'\fR optimise silencieusement \f(CW\*(C`/^/\*(C'\fR en \&\f(CW\*(C`/^/m\*(C'\fR. .Sh "Les ope\*'rateurs d'E/S" .IX Subsection "Les ope'rateurs d'E/S" Il y a plusieurs ope\*'rateurs d'E/S (Entre\*'e/Sortie) que vous devez connai\*^tre. .PP Une chai\*^ne entoure\*'e d'apostrophes inverse\*'es (accents graves) subit tout d'abord une substitution des variables exactement comme une chai\*^ne entre guillemets. Elle est ensuite interpre\*'te\*'e comme une commande et la sortie de cette commande est la valeur du pseudo\-litte\*'ral comme avec un shell. Dans un contexte scalaire, la valeur retourne\*'e est une seule chai\*^ne constitue\*'e de toutes les lignes de la sortie. Dans un contexte de liste, une liste de valeurs est retourne\*'e, chacune des ces valeurs contenant une ligne de la sortie. (Vous pouvez utilisez \f(CW$/\fR pour utiliser un terminateur de ligne diffe\*'rent.) La commande est exe\*'cute\*'e a\*` chaque fois que le pseudo\-litte\*'ral est e\*'value\*'. La valeur du statut de la commande est retourne\*'e dans \f(CW$?\fR (voir perlvar pour l'interpre\*'tation de \f(CW$?\fR). A\*` l'inverse de \fBcsh\fR, aucun traitement n'est applique\*' aux valeurs retourne\*'es \*(-- les passages a\*` la ligne restent des passages a\*` la ligne. A l'inverse de la plupart des shells, les apostrophes inverse\*'es n'empe\*^chent pas l'interpre\*'tation des noms de variables dans la commande. Pour passer litte\*'ralement un $ au shell, vous devez le prote\*'ger en le pre\*'fixant par un backslash (barre oblique inverse\*'e). La forme ge\*'ne\*'rale des apostrophes inverse\*'es est \f(CW\*(C`qx//\*(C'\fR. (Puisque les apostrophes inverse\*'es impliquent toujours un passage par l'interpre\*'tation du shell, voir perlsec pour tout ce qui concerne la se\*'curite\*'.) .PP Dans un contexte scalaire, e\*'valuer un filehandle entre supe\*'rieur/infe\*'rieur produit le ligne suivante de ce fichier (saut a\*` la ligne inclus si il y a lieu) ou \f(CW\*(C`undef\*(C'\fR a\*` la fin du fichier. Lorsque \f(CW$/\fR a pour valeur \f(CW\*(C`undef\*(C'\fR (i.e. le mode \fIfile slurp\fR) et que le fichier est vide, \f(CW''\fR est retourne\*' lors de la premie\*`re lecture puis ensuite \f(CW\*(C`undef\*(C'\fR. .PP Normalement vous devez affecter cette valeur a\*` une variable mais il y a un cas ou\*` une affectation automagique a lieu. Si et seulement si cette ope\*'rateur d'entre\*'e est la seule chose pre\*'sente dans la condition d'une boucle \f(CW\*(C`while\*(C'\fR ou \f(CW\*(C`for(;;)\*(C'\fR alors la valeur est automagiquement affecte\*'e a\*` la variable \&\f(CW$_\fR. (Cela peut vous sembler bizarre, mais vous utiliserez de telles constructions dans la plupart des scripts Perl que vous e\*'crirez.) La variable \&\f(CW$_\fR n'est pas implicitement local\-ise\*'e. Vous devrez donc le faire explicitement en mettant \f(CW\*(C`local $_;\*(C'\fR. .PP Les lignes suivantes sont toutes e\*'quivalentes\ : .PP .Vb 7 \& while (defined($_ = )) { print; } \& while ($_ = ) { print; } \& while () { print; } \& for (;;) { print; } \& print while defined($_ = ); \& print while ($_ = ); \& print while ; .Ve .PP et celle-ci a un comportement similaire mais sans utiliser \f(CW$_\fR\ : .PP .Vb 1 \& while (my $line = ) { print $line } .Ve .PP Dans ces constructions, la valeur affecte\*'e (que ce soit automagiquement ou explicitement) est ensuite teste\*'e pour savoir si elle est de\*'finie. Ce test de de\*'finition e\*'vite les proble\*`mes avec des lignes qui ont une valeur qui pourrait e\*^tre interpre\*'te\*'e comme fausse par perl comme par exemple "\*(L" ou \*(R"0" sans passage a\*` la ligne derrie\*`re. Si vous voulez re\*'ellement tester la valeur de la ligne pour terminer votre boucle, vous devrez la tester explicitement\ : .PP .Vb 2 \& while (($_ = ) ne '0') { ... } \& while () { last unless $_; ... } .Ve .PP Dans tous les autres contextes boole\*'ens, \f(CW\*(C`<\f(CIfilehandle\f(CW>\*(C'\fR sans un test explicite de de\*'finition (par \f(CW\*(C`defined\*(C'\fR) de\*'clenchera un message d'avertissement si le pragma \f(CW\*(C`use warnings\*(C'\fR ou l'option \f(CW\*(C`\-w\*(C'\fR (c'est a\*` dire la variable \f(CW$^W\fR) est actif. .PP Les filehandles \s-1STDIN\s0, \s-1STDOUT\s0, et \s-1STDERR\s0 sont pre\*'de\*'finis. (Les filehandles \&\f(CW\*(C`stdin\*(C'\fR, \f(CW\*(C`stdout\*(C'\fR, et \f(CW\*(C`stderr\*(C'\fR fonctionnent aussi excepte\*'s dans les packages ou\*` ils sont interpre\*'te\*'s comme des identifiants locaux.) Des filehandles supple\*'mentaires peuvent e\*^tre cre\*'e\*'s par la fonction \fIopen()\fR. Voir perlopentut et \*(L"open\*(R" in perlfunc pour plus de de\*'tails. .PP Si <\s-1FILEHANDLE\s0> est utilise\*' dans un contexte de liste, une liste constitue\*'e de toutes les lignes est retourne\*'e avec une ligne par e\*'le\*'ment de la liste. Il est facile d'utiliser de grande quantite\*' de me\*'moire par ce moyen. Donc, a\*` utiliser avec pre\*'caution. .PP <\s-1FILEHANDLE\s0> peut aussi e\*^tre e\*'crit \f(CW\*(C`readline(*FILEHANDLE)\*(C'\fR. Voir \&\*(L"readline\*(R" in perlfunc. .PP Le filehandle vide <> est spe\*'cial et peut e\*^tre utiliser pour e\*'muler le comportement de \fBsed\fR et de \fBawk\fR. L'entre\*'e de <> provient soit de l'entre\*'e standard soit de tous les fichiers liste\*'s sur la ligne de commande. Voici comment c\*,a marche : la premie\*`re fois que <> est e\*'value\*', on teste le tableau \f(CW@ARGV\fR et s'il est vide alors \f(CW$ARGV[0]\fR est positionne\*' a\*` \*(L"\-\*(R" qui lorsqu'il sera ouvert lira l'entre\*'e standard. Puis le tableau \f(CW@ARGV\fR est traite\*' comme une liste de nom de fichiers. La boucle\ : .PP .Vb 3 \& while (<>) { \& ... # code pour chaque ligne \& } .Ve .PP est e\*'quivalent au pseudo-code Perl suivant\ : .PP .Vb 7 \& unshift(@ARGV, '\-') unless @ARGV; \& while ($ARGV = shift) { \& open(ARGV, $ARGV); \& while () { \& ... # code pour chaque ligne \& } \& } .Ve .PP sauf qu'il est moins volumineux et qu'il marche re\*'ellement. Il de\*'cale vraiment le tableau \f(CW@ARGV\fR et stocke le nom du fichier courant dans la variable \&\f(CW$ARGV\fR. Il utilise aussi en interne le filehandle \fI\s-1ARGV\s0\fR \*(-- <> est simplement un synonyme de <\s-1ARGV\s0> qui est magique. (Le pseudo-code pre\*'ce\*'dent ne fonctionne pas car il tient pas compte de l'aspect magique de <\s-1ARGV\s0>.) .PP Vous pouvez modifier \f(CW@ARGV\fR avant la premier <> tant que vous y laissez la liste des noms de fichiers que vous voulez. Le nume\*'ro de ligne (\f(CW$.\fR) augmente exactement comme si vous aviez un seul gros fichier. Regardez l'exemple de \f(CW\*(C`eof\*(C'\fR pour savoir comment le re\*'initialiser a\*` chaque fichier. .PP Si vous voulez affecter a\*` \f(CW@ARGV\fR votre propre liste de fichiers, proce\*'dez de la manie\*`re suivante. La ligne suivante positionne \f(CW@ARGV\fR a\*` tous les fichiers de type texte si aucun \f(CW@ARGV\fR n'est fourni\ : .PP .Vb 1 \& @ARGV = grep { \-f && \-T } glob('*') unless @ARGV; .Ve .PP Vous pouvez me\*^me les positionner avec des commandes pipe (tube). Par exemple, la ligne suivante applique automatiquement \fBgzip\fR aux arguments compresse\*'s\ : .PP .Vb 1 \& @ARGV = map { /\e.(gz|Z)$/ ? "gzip \-dc < $_ |" : $_ } @ARGV; .Ve .PP Si vous voulez passer des options a\*` votre script, vous pouvez utiliser l'un des modules Getopts ou placer au de\*'but de votre script une boucle du type\ : .PP .Vb 7 \& while ($_ = $ARGV[0], /^\-/) { \& shift; \& last if /^\-\-$/; \& if (/^\-D(.*)/) { $debug = $1 } \& if (/^\-v/) { $verbose++ } \& # ... # autres options \& } \& \& while (<>) { \& # ... # code pour chaque ligne \& } .Ve .PP Le symbole <> retournera \f(CW\*(C`undef\*(C'\fR a\*` la fin des fichiers une seule fois. Si vous l'appelez encore une fois apre\*`s, il supposera que vous voulez traiter une nouvelle liste \f(CW@ARGV\fR et, si vous n'avez pas rempli \f(CW@ARGV\fR, il traitera l'entre\*'e \s-1STDIN\s0. .PP Si la chai\*^ne entre supe\*'rieur/infe\*'rieur est une re\*'fe\*'rence a\*` une variable scalaire (e.g. <$foo>) alors cette variable doit contenir le nom du filehandle a\*` utiliser comme entre\*'e ou son typeglob ou une re\*'fe\*'rence vers un typeglob. Par exemple\ : .PP .Vb 2 \& $fh = \e*STDIN; \& $line = <$fh>; .Ve .PP Si ce qui est entre supe\*'rieur/infe\*'rieur n'est ni un filehandle, ni une simple variable scalaire contenant un nom de filehandle, un typeglob ou une re\*'fe\*'rence a\*` un typeglob, il est alors interpre\*'te\*' comme un motif de nom de fichier a\*` appliquer et ce qui est retourne\*' est soit la liste de tous les noms de fichiers ou juste le nom suivant dans la liste selon le contexte. La distinction n'est faite que par la syntaxe. Cela signifie que \f(CW\*(C`<$x>\*(C'\fR est toujours la lecture d'une ligne a\*` partir d'un handle indirect mais que \&\f(CW\*(C`<$hash{key}>\*(C'\fR est toujours un motif de nom de fichiers. Tout cela parce que \f(CW$x\fR est une simple variable scalaire alors que \f(CW$hash{key}\fR ne l'est pas \*(-- c'est un e\*'le\*'ment d'une table de hachage. .PP Comme pour les chai\*^nes entre guillemets, un niveau d'interpre\*'tation est applique\*' au pre\*'alable mais vous ne pouvez pas dire \f(CW\*(C`<$foo>\*(C'\fR parce que c'est toujours interpre\*'te\*' comme un filehandle indirect (explications du paragraphe pre\*'ce\*'dent). (Dans des versions ante\*'rieures de Perl, les programmeurs inse\*'raient des accolades pour forcer l'interpre\*'tation comme un motif de nom de fichier: \f(CW\*(C`<${foo}>\*(C'\fR. De nos jours, il est conside\*'re\*' plus propre d'appeler la fonction interne explicitement par \f(CW\*(C`glob($foo)\*(C'\fR qui est probablement la meilleure fac\*,on de faire dans le premier cas.) Exemple\ : .PP .Vb 3 \& while (<*.c>) { \& chmod 0644, $_; \& } .Ve .PP est e\*'quivalent a\*`\ : .PP .Vb 5 \& open(FOO, "echo *.c | tr \-s ' \et\er\ef' '\e\e012\e\e012\e\e012\e\e012'|"); \& while () { \& chop; \& chmod 0644, $_; \& } .Ve .PP sauf que la recherche des fichiers est faite en interne par l'extension standard \f(CW\*(C`File::Glob\*(C'\fR. Bien su\*^r, le moyen le plus court d'obtenir le re\*'sultat pre\*'ce\*'dent est\ : .PP .Vb 1 \& chmod 0644, <*.c>; .Ve .PP Un motif de noms de fichier e\*'value ses arguments uniquement lorsqu'il de\*'bute une nouvelle liste. Toutes les valeurs doivent e\*^tre lues avant de recommencer. Dans un contexte de liste, cela n'a aucune importance puisque vous re\*'cupe\*'rez toutes les valeurs quoi qu'il arrive. Dans un contexte scalaire, par contre, l'ope\*'rateur retourne la valeur suivante a\*` chaque fois qu'il est appele\*' ou la valeur \f(CW\*(C`undef\*(C'\fR a\*` la fin. Comme pour les filehandles un \&\f(CW\*(C`defined\*(C'\fR automatique est ge\*'ne\*'re\*' lorsque l'ope\*'rateur est utilise\*' comme test d'un \f(CW\*(C`while\*(C'\fR ou d'un \f(CW\*(C`for\*(C'\fR \- car sinon certains noms de fichier le\*'gaux (e.g. un fichier nomme\*' \fI0\fR) risquent de terminer la boucle. Encore une fois, \&\f(CW\*(C`undef\*(C'\fR n'est retourne\*' qu'une seule fois. Donc si vous n'attendez qu'une seule valeur, il vaut mieux e\*'crire\ : .PP .Vb 1 \& ($file) = ; .Ve .PP que\ : .PP .Vb 1 \& $file = ; .Ve .PP car dans le dernier cas vous aurez soit un nom de fichier soit faux. .PP Si vous avez besoin de l'interpolation de variables, il est de\*'finitivement meilleur d'utiliser la fonction \fIglob()\fR parce que l'ancienne notation peut e\*^tre confondu avec la notation des filehandles indirects. .PP .Vb 2 \& @files = glob("$dir/*.[ch]"); \& @files = glob($files[$i]); .Ve .Sh "Traitement des constantes" .IX Subsection "Traitement des constantes" Comme en C, Perl e\*'value un certain nombre d'expressions lors de la compilation lorsqu'il peut de\*'terminer que tous les arguments d'un ope\*'rateur sont statiques et n'ont aucun effet de bord. En particulier, la concate\*'nation de chai\*^nes a lieu lors de la compilation entre deux litte\*'raux qui ne sont pas soumis a\*` l'interpolation de variables. L'interpre\*'tation du backslash (barre oblique inverse\*'e) a lieu elle aussi lors de la compilation. Vous pouvez dire\ : .PP .Vb 2 \& 'Now is the time for all' . "\en" . \& 'good men to come to.' .Ve .PP qui sera re\*'duit a\*` une seule chai\*^ne de manie\*`re interne. Vous pouvez aussi dire\ : .PP .Vb 3 \& foreach $file (@filenames) { \& if (\-s $file > 5 + 100 * 2**16) { } \& } .Ve .PP le compilateur pre\*'\-calculera la valeur repre\*'sente\*'e par l'expression et l'interpre\*'teur n'aura plus a\*` le faire. .Sh "Ope\*'rateurs bit a\*` bit sur les chai\*^nes" .IX Subsection "Ope'rateurs bit a` bit sur les chai^nes" Les chai\*^nes de bits de longueur arbitraire peuvent e\*^tre manipule\*'es par les ope\*'rateurs bit a\*` bit (\f(CW\*(C`~ | & ^\*(C'\fR). .PP Si les ope\*'randes d'un ope\*'rateur bit a\*` bit sont des chai\*^nes de longueurs diffe\*'rentes, les ope\*'rateurs \fB|\fR et \fB^\fR agiront comme si l'ope\*'rande le plus court e\*'tait comple\*'te\*' par des bits a\*` ze\*'ro a\*` droite alors que l'ope\*'rateur \fB&\fR agira comme si l'ope\*'rande le plus long e\*'tait tronque\*' a\*` la longueur du plus court. Notez que la granularite\*' pour de telles extensions ou troncations est d'un ou plusieurs octets. .PP .Vb 5 \& # Exemples ASCII \& print "j p \en" ^ " a h"; # affiche "JAPH\en" \& print "JA" | " ph\en"; # affiche "japh\en" \& print "japh\enJunk" & '_\|_\|_\|_\|_'; # affiche "JAPH\en"; \& print 'p N$' ^ " E>\*(R") produisent toujours des re\*'sultats entiers. (Mais voir aussi \&\*(L"Ope\*'rateurs bit a\*` bit sur les chai\*^nes\*(R".) Par contre, \f(CW\*(C`use integer\*(C'\fR a encore une influence sur eux. Par de\*'faut, leurs re\*'sultats sont interpre\*'te\*'s comme des entiers non\-signe\*'s. Par contre, si \f(CW\*(C`use integer\*(C'\fR est actif, leurs re\*'sultats sont interpre\*'te\*'s comme des entiers signe\*'s. Par exemple, \f(CW\*(C`~0\*(C'\fR est habituellement e\*'value\*' comme un grande valeur entie\*`re. Par contre, \f(CW\*(C`use integer; ~0\*(C'\fR donne \-1 sur des machines a\*` comple\*'ment a\*` deux. .Sh "Arithme\*'tique en virgule flottante" .IX Subsection "Arithme'tique en virgule flottante" Bien que \f(CW\*(C`use integer\*(C'\fR propose une arithme\*'tique uniquement entie\*`re, il n'y a aucun moyen similaire d'imposer des arrondis ou des troncations a\*` un certain nombre de de\*'cimales. Pour arrondir a\*` un nombre de de\*'cimales pre\*'cis, la me\*'thode la plus simple est d'utiliser \fIsprintf()\fR ou \fIprintf()\fR. .PP Les nombres en virgule flottante ne sont qu'une approximation de ce que les mathe\*'maticiens appellent les nombres re\*'els. Il y a infiniment plus de re\*'els que de flottants donc il faut arrondir quelques angles. Par exemple\ : .PP .Vb 2 \& printf "%.20g\en", 123456789123456789; \& # produit 123456789123456784 .Ve .PP Tester l'e\*'galite\*' ou l'ine\*'galite\*' exacte de nombres flottants n'est pas une bonne ide\*'e. Voici un moyen (relativement cou\*^teux) pour tester l'e\*'galite\*' de deux nombres flottants sur un nombre particulier de de\*'cimales. Voir le volume \&\s-1II\s0 de Knuth pour un traitement plus robuste de ce sujet. .PP .Vb 7 \& sub fp_equal { \& my ($X, $Y, $POINTS) = @_; \& my ($tX, $tY); \& $tX = sprintf("%.${POINTS}g", $X); \& $tY = sprintf("%.${POINTS}g", $Y); \& return $tX eq $tY; \& } .Ve .PP Le module \s-1POSIX\s0 (qui fait partie de la distribution standard de perl) imple\*'mente \fIceil()\fR, \fIfloor()\fR et un certain nombre d'autres fonctions mathe\*'matiques et trigonome\*'triques. Le module Math::Complex (qui fait partie de la distribution standard de perl) de\*'finit de nombreuses fonctions mathe\*'matiques qui fonctionnent aussi bien sur des nombres re\*'els que sur des nombres complexes. Math::Complex n'est pas aussi performant que \s-1POSIX\s0 mais \&\s-1POSIX\s0 ne peut pas travailler avec des nombres complexes. .PP Arrondir dans une application financie\*`re peut avoir de se\*'rieuses implications et la me\*'thode d'arrondi utilise\*'e doit e\*^tre spe\*'cifie\*'e pre\*'cise\*'ment. Dans ce cas, il peut e\*^tre plus su\*^r de ne pas faire confiance aux diffe\*'rents syste\*`mes d'arrondi propose\*'s par Perl mais pluto\*^t d'imple\*'menter vous\-me\*^mes la fonction d'arrondi dont vous avez besoin. .Sh "Les grands nombres" .IX Subsection "Les grands nombres" Les modules standard Math::BigInt et Math::BigFloat fournissent des variables arithme\*'tiques en pre\*'cision infinie et rede\*'finissent les ope\*'rateurs correspondants. Au prix d'un peu d'espace et de beaucoup de temps, ils permettent d'e\*'viter les embu\*^ches classiques associe\*'es aux repre\*'sentations en pre\*'cision limite\*'e. .PP .Vb 3 \& use Math::BigInt; \& $x = Math::BigInt\->new('123456789123456789'); \& print $x * $x; \& \& # affiche +15241578780673678515622620750190521 .Ve .PP Les modules non standard SSLeay::BN et Math::Pari founissent des fonctionnalite\*'s e\*'quivalentes (et me\*^me supe\*'rieures) avec de meilleures performances. .SH "TRADUCTION" .IX Header "TRADUCTION" .Sh "Version" .IX Subsection "Version" Cette traduction franc\*,aise correspond a\*` la version anglaise distribue\*'e avec perl 5.6.0. Pour en savoir plus concernant ces traductions, consultez . .Sh "Traducteur" .IX Subsection "Traducteur" Traduction initiale et mise a\*` jour Paul Gaborit . .Sh "Relecture" .IX Subsection "Relecture" Personne pour l'instant.