.\" Automatically generated by Pod::Man 2.09 (Pod::Simple 3.04) .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "PERLSUB 1" .TH PERLSUB 1 "2006-03-20" "DocFr" "User Contributed Perl Documentation" .SH "NAME/NOM" .IX Xref "subroutine sous-programme fonction" .IX Header "NAME/NOM" perlsub \- Les sous-programmes (ou subroutines) de Perl .SH "SYNOPSIS" .IX Header "SYNOPSIS" Pour de\*'clarer des sous-programmes\ : .IX Xref "de\*'claration de sous-programmes sous-programme, de\*'claration sub" .PP .Vb 4 \& sub NAME; # Une de\*'claration "en avant". \& sub NAME(PROTO); # idem, mais avec des prototypes \& sub NAME : ATTRS; # avec attributs \& sub NAME(PROTO) : ATTRS; # avec attributs et prototypes \& \& sub NAME BLOCK # Une de\*'claration et une de\*'finition. \& sub NAME(PROTO) BLOCK # idem, mais avec des prototypes \& sub NAME : ATTRS BLOCK # avec attributs \& sub NAME(PROTO) : ATTRS BLOCK # avec attributs et prototypes .Ve .PP Pour de\*'finir un sous-programme anonyme lors de l'exe\*'cution\ : .IX Xref "sous-programme anonyme" .PP .Vb 4 \& $subref = sub BLOCK; # pas de prototype \& $subref = sub (PROTO) BLOCK; # avec prototype \& $subref = sub : ATTRS BLOCK; # avec attributs \& $subref = sub (PROTO) : ATTRS BLOCK; # avec proto et attributs .Ve .PP Pour importer des sous-programmes\ : .IX Xref "import" .PP .Vb 1 \& use MODULE qw(NAME1 NAME2 NAME3); .Ve .PP Pour appeler des sous-programmes\ : .IX Xref "appel de sous-programmes sous-programme, appel" .PP .Vb 6 \& NAME(LIST); # & est optionnel avec les parenthe\*`ses. \& NAME LIST; # Les parenthe\*`ses sont optionnelles si le \& # sous\-programme est pre\*'de\*'clare\*' ou importe\*'. \& &NAME(LIST); # Court\-circuite les prototypes. \& &NAME; # Rend la @_ courante visible par le \& # sous\-programme appele\*'. .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Comme beaucoup de langages, Perl fournit des sous-programmes de\*'finis par l'utilisateur. Ils peuvent se trouver n'importe ou\*` dans le programme principal. Ils peuvent e\*^tre charge\*'s depuis d'autres fichiers via les mots\-cle\*'s \f(CW\*(C`do\*(C'\fR, \f(CW\*(C`require\*(C'\fR ou \f(CW\*(C`use\*(C'\fR, ou e\*^tre ge\*'ne\*'re\*'s a\*` la vole\*'e en utilisant \f(CW\*(C`eval\*(C'\fR ou des sous-programmes anonymes. Vous pouvez me\*^me appeler une fonction indirectement en utilisant une variable contenant son nom ou une re\*'fe\*'rence a\*` du \s-1CODE\s0. .PP Le mode\*`le de Perl pour l'appel de fonction et le renvoi de valeurs est simple\ : tous les parame\*`tres sont passe\*'s aux fonctions comme une simple liste de scalaires, et toutes les fonctions renvoient de la me\*^me manie\*`re a\*` leur appelant une simple liste de scalaires. Tout tableau ou hachage dans ces listes d'appel et de retour s'effondreront, perdant leur identite\*' \*(-- mais vous pouvez toujours utiliser le passage par re\*'fe\*'rence a\*` la place pour e\*'viter cela. Les listes d'appel ou de retour peuvent contenir autant d'e\*'le\*'ments scalaires que vous le de\*'sirez (une fonction sans instruction de retour explicite est souvent appele\*'e un sous\-programme, mais il n'y a vraiment pas de diffe\*'rence du point de vue de Perl). .IX Xref "parame\*`tres d'un sous-programme sous-programme, parame\*`tre parame\*`tre" .PP Tous les arguments passe\*'s a\*` la routine se retrouvent dans le tableau \&\f(CW@_\fR. Ainsi, si vous appelez une fonction avec deux arguments, ceux-ci seront stocke\*'s dans \f(CW$_[0]\fR et \f(CW$_[1]\fR. Le tableau \f(CW@_\fR est un tableau local, mais ses e\*'le\*'ments sont des alias pour les ve\*'ritables parame\*`tres scalaires. En particulier, si un e\*'le\*'ment \f(CW$_[0]\fR est mis a\*` jour, l'argument correspondant est mis a\*` jour (ou bien une erreur se produit s'il n'est pas modifiable). Si un argument est un e\*'le\*'ment de tableau ou de hachage qui n'existait pas lors de l'appel de la fonction, cet e\*'le\*'ment est cre\*'e\*' seulement lorsque (et si) il est modifie\*' ou si on y fait re\*'fe\*'rence (certaines versions pre\*'ce\*'dentes de Perl cre\*'aient l'e\*'le\*'ment qu'il soit ou non affecte\*'). L'affectation a\*` la totalite\*' du tableau \f(CW@_\fR retire les alias, et ne met a\*` jour aucun argument. .IX Xref "sous-programme, argument arguments d'un sous-programme argument @_" .PP Une instruction \f(CW\*(C`return\*(C'\fR peut e\*^tre utilise\*'e pour sortir d'un sous\-programme, en spe\*'cifiant e\*'ventuellement une valeur de retour, qui sera e\*'value\*'e dans le contexte approprie\*' (liste, scalaire ou vide) selon le contexte d'appel du sous\-programme. Si vous ne spe\*'cifiez aucune valeur de retour, le sous-programme retourne une liste vide dans un contexte de liste, la valeur inde\*'finie dans un contexte scalaire et rien du tout dans un contexte vide. Si vous retournez un ou plusieurs aggre\*'gats (tableau ou table de hachage), ils seront tous applatis en une seule grande liste. .PP Si aucun \f(CW\*(C`return\*(C'\fR n'est trouve\*' et si la dernie\*`re instruction est une expression, sa valeur est retourne\*'e. Si la dernie\*`re instruction est une structure de contro\*^le de boucle comme \f(CW\*(C`foreach\*(C'\fR ou \f(CW\*(C`while\*(C'\fR, la valeur retourne\*'e est non spe\*'cifie\*'e. Un sous-programme vide retourne une liste vide. .IX Xref "sous-programme, valeur de retour valeur de retour retour" .PP Perl n'a pas de parame\*`tres formels nomme\*'s. En pratique tout ce que vous avez a\*` faire est d'affecter a\*` une liste \f(CW\*(C`my()\*(C'\fR les contenant. Les variables que vous utilisez dans la fonction et qui ne sont pas de\*'clare\*'es comme prive\*'es sont des variables globales. Pour des de\*'tails sanglants sur la cre\*'ation de variables prive\*'es, voir \&\*(L"Variables prive\*'es via \fImy()\fR\*(R" et \*(L"Valeurs temporaires via \&\fIlocal()\fR\*(R". Pour cre\*'er des environnement prote\*'ge\*'s pour un ensemble de fonctions dans un paquetage se\*'pare\*' (et probablement un fichier se\*'pare\*'), voir \*(L"Paquetages\*(R" in perlmod. .IX Xref "parame\*`tre formel" .PP Exemple\ : .PP .Vb 8 \& sub max { \& my $max = shift(@_); \& foreach $foo (@_) { \& $max = $foo if $max < $foo; \& } \& return $max; \& } \& $bestday = max($mon,$tue,$wed,$thu,$fri); .Ve .PP Exemple\ : .PP .Vb 2 \& # obtient une ligne, en y combinant les lignes la continuant qui \& # de\*'butent par un blanc \& \& sub get_line { \& $thisline = $lookahead; # Variables globales !! \& LINE: while (defined($lookahead = )) { \& if ($lookahead =~ /^[ \et]/) { \& $thisline .= $lookahead; \& } \& else { \& last LINE; \& } \& } \& return $thisline; \& } \& \& $lookahead = ; # obtient la premie\*`re ligne \& while (defined($line = get_line()) { \& ... \& } .Ve .PP Affectez a\*` une liste de variables prive\*'es pour nommer vos arguments\ : .PP .Vb 4 \& sub maybeset { \& my($key, $value) = @_; \& $Foo{$key} = $value unless $Foo{$key}; \& } .Ve .PP Puisque l'affectation copie les valeurs, ceci a aussi pour effet de transformer l'appel par re\*'fe\*'rence en appel par valeur. Autrement, une fonction est libre de faire des modifications de \f(CW@_\fR sur place et de changer les valeurs de son appelant. .IX Xref "appel par re\*'fe\*'rence appel par valeur" .PP .Vb 4 \& upcase_in($v1, $v2); # ceci change $v1 et $v2 \& sub upcase_in { \& for (@_) { tr/a\-z/A\-Z/ } \& } .Ve .PP Vous n'avez pas le droit de modifier les constantes de cette fac\*,on, bien su\*^r. Si un argument e\*'tait en ve\*'rite\*' un litte\*'ral et que vous essayiez de le changer, vous le\*`veriez une exception (probablement fatale). Par exemple, ceci ne fonctionnera pas\ : .IX Xref "appel par re\*'fe\*'rence appel par valeur" .PP .Vb 1 \& upcase_in("frederick"); .Ve .PP Ce serait bien plus su\*^r si la fonction \f(CW\*(C`upcase_in()\*(C'\fR e\*'tait e\*'crite de fac\*,on a\*` renvoyer une copie de ses parame\*`tres au lieu de les changer sur place\ : .PP .Vb 7 \& ($v3, $v4) = upcase($v1, $v2); # cela ne change pas $v1 et $v2 \& sub upcase { \& return unless defined wantarray; # contexte vide, ne fait rien \& my @parms = @_; \& for (@parms) { tr/a\-z/A\-Z/ } \& return wantarray ? @parms : $parms[0]; \& } .Ve .PP Notez comment cette fonction (non prototype\*'e) ne se soucie pas qu'on lui ait passe\*' de vrais scalaires ou des tableaux. Perl voit tous les arguments comme une grosse et longue liste plate de parame\*`tres dans \&\f(CW@_\fR. C'est un domaine dans lequel brille le style simple de passage d'arguments de Perl. La fonction \f(CW\*(C`upcase()\*(C'\fR fonctionnerait parfaitement bien sans avoir a\*` changer la de\*'finition de \f(CW\*(C`upcase()\*(C'\fR me\*^me si nous lui donnions des choses telles que ceci\ : .PP .Vb 2 \& @newlist = upcase(@list1, @list2); \& @newlist = upcase( split /:/, $var ); .Ve .PP Ne vous laissez toutefois pas tenter de faire\ : .PP .Vb 1 \& (@a, @b) = upcase(@list1, @list2); .Ve .PP Tout comme la liste plate de parame\*`tres entrante, la liste de retour est aussi aplatie. Donc tout ce que vous e\*^tes parvenu a\*` faire ici est de tout stocker dans \f(CW@a\fR et de vider \f(CW@b\fR. Voir \*(L"Passage par re\*'fe\*'rence\*(R" pour savoir comment faire autrement. .PP Un sous-programme peut e\*^tre appele\*' en utilisant un pre\*'fixe \f(CW\*(C`&\*(C'\fR explicite. Le \f(CW\*(C`&\*(C'\fR est optionnel en Perl moderne, tout comme le sont les parenthe\*`ses si le sous-programme a e\*'te\*' pre\*'de\*'clare\*'. Le \f(CW\*(C`&\*(C'\fR n'est \&\fIpas\fR optionnel lorsque l'on nomme juste le sous\-programme, comme lorsqu'il est utilise\*' en tant qu'argument de \fIdefined()\fR ou de \&\fIundef()\fR. Il n'est pas non plus optionnel lorsque vous voulez faire un appel indirect de sous-programme avec le nom d'un sous-programme ou une re\*'fe\*'rence utilisant les constructions \f(CW\*(C`&$subref()\*(C'\fR ou \&\f(CW\*(C`&{$subref}()\*(C'\fR, bien que la notation \f(CW\*(C`$subref\->()\*(C'\fR re\*'soud ce proble\*`me. Voir perlref pour plus de de\*'tails a\*` ce sujet. .IX Xref "&" .PP Les sous-programmes peuvent e\*^tre appele\*'s de fac\*,on re\*'cursive. Si un sous-programme est appele\*' en utilisant la forme \f(CW\*(C`&\*(C'\fR, la liste d'arguments est optionnelle, et si elle est omise, aucun tableau \f(CW@_\fR n'est mis en place pour le sous-programme\ : le tableau \f(CW@_\fR au moment de l'appel est visible a\*` la place dans le sous\-programme. C'est un me\*'canisme d'efficacite\*' que les nouveaux utilisateurs pourraient pre\*'fe\*'rer e\*'viter. .IX Xref "re\*'cursivite\*' sous-programme re\*'cursif" .PP .Vb 2 \& &foo(1,2,3); # passe trois arguments \& foo(1,2,3); # idem \& \& foo(); # passe une liste nulle \& &foo(); # idem \& \& &foo; # foo() obtient les arguments courants, comme foo(@_) !! \& foo; # comme foo() SI le sous\-programme foo est \& # pre\*'de\*'clare\*', sinon "foo" .Ve .PP Non seulement la forme \f(CW\*(C`&\*(C'\fR rend la liste d'arguments optionnelle, mais elle de\*'sactive aussi toute ve\*'rification de prototype sur les arguments que vous fournissez. C'est en partie pour des raisons historiques, et en partie pour avoir une fac\*,on pratique de tricher si vous savez ce que vous e\*^tes en train de faire. Voir Prototypes ci\-dessous. .IX Xref "&" .PP Les sous-programme dont les noms sont entie\*`rement en majuscules sont re\*'serve\*'es pour le noyau de Perl, tout comme les modules dont les noms sont entie\*`rement en minuscules. Une fonction entie\*`rement en majuscules est une convention informelle signifiant qu'elle sera appele\*'e indirectement par le syste\*`me d'exe\*'cution lui\-me\*^me, habituellement en re\*'ponse a\*` un e\*'ve\*'nement. Les sous-programmes qui font des choses spe\*'ciales pre\*'de\*'finies sont entre autres \f(CW\*(C`AUTOLOAD\*(C'\fR, \f(CW\*(C`CLONE\*(C'\fR et \&\f(CW\*(C`DESTROY\*(C'\fR \*(-- plus toutes les fonctions mentionne\*'es dans perltie et PerlIO::via. .PP Les sous-programmes \f(CW\*(C`BEGIN\*(C'\fR, \f(CW\*(C`CHECK\*(C'\fR, \f(CW\*(C`INIT\*(C'\fR et \f(CW\*(C`END\*(C'\fR sont pluto\*^t des blocs spe\*'ciaux, de code, nomme\*'s, qui peuvent apparai\*^tre plusieurs fois dans un paquetage et qu'il vous est \fBimpossible\fR d'appeler explicitement. Voir \*(L"\s-1BEGIN\s0, \s-1CHECK\s0, \s-1INIT\s0 et \s-1END\s0\*(R" in perlmod. .Sh "Variables prive\*'es via \fImy()\fP" .IX Subsection "Variables prive'es via my()" .IX Xref "my variable lexicale lexical lexicale, variable porte\*'e lexicale lexicale, porte\*'e attributs my" .PP Synopsis: .PP .Vb 5 \& my $foo; # de\*'clare $foo locale lexicalement \& my (@wid, %get); # de\*'clare une liste de variables locale \& my $foo = "flurp"; # de\*'clare $foo lexical, et l'initialise \& my @oof = @bar; # de\*'clare @oof lexical, et l'initialise \& my $x : Foo = $y; # similaire, avec application d'un attribut .Ve .PP \&\fB\s-1AVERTISSEMENT\s0\fR\ : l'usage de listes d'attributs sur les de\*'clarations \&\f(CW\*(C`my\*(C'\fR est expe\*'rimental. La se\*'mantique pre\*'cise et l'interface associe\*'e sont sujettes a\*` changement. Voir attributes et Attribute::Handlers. .PP L'ope\*'rateur \f(CW\*(C`my\*(C'\fR de\*'clare que les variables liste\*'es doivent e\*^tre confine\*'es lexicalement au bloc ou\*` elles se trouvent, dans la conditionnelle (\f(CW\*(C`if/unless/elsif/else\*(C'\fR), la boucle (\f(CW\*(C`for/foreach/while/until/continue\*(C'\fR), le sous\-programme, l'\f(CW\*(C`eval\*(C'\fR, ou le fichier exe\*'cute\*', requis ou utilise\*' via \f(CW\*(C`do/require/use\*(C'\fR. Si plus d'une valeur est liste\*'e, la liste doit e\*^tre place\*'e entre parenthe\*`ses. Tous les e\*'le\*'ments liste\*'s doivent e\*^tre des lvalues le\*'gales. Seuls les identifiants alphanume\*'riques peuvent avoir une porte\*'e lexicale \*(-- pour l'instant1, les identifiants magiques pre\*'de\*'finis comme \f(CW$/\fR peuvent, a\*` la place, e\*^tre localise\*'s par \&\f(CW\*(C`local\*(C'\fR. .PP Contrairement aux variables dynamiques cre\*'e\*'es par l'ope\*'rateur \&\f(CW\*(C`local\*(C'\fR, les variables lexicales de\*'clare\*'es par \f(CW\*(C`my\*(C'\fR sont totalement cache\*'es du monde exte\*'rieur, y compris de tout sous-programme appele\*'. Cela est vrai s'il s'agit du me\*^me sous-programme rappele\*' depuis lui\-me\*^me ou depuis un autre endroit \*(-- chaque appel obtient sa propre copie. .IX Xref "local" .PP Ceci ne veut pas dire qu'une variable \f(CW\*(C`my()\*(C'\fR de\*'clare\*'e dans une porte\*'e lexicale englobante statiquement serait invisible. Seules les porte\*'es dynamiques sont re\*'tre\*'cies. Par exemple, la fonction \f(CW\*(C`bumpx()\*(C'\fR ci-dessous a acce\*`s a\*` la variable lexicale \f(CW$x\fR car le \f(CW\*(C`my\*(C'\fR et le \&\f(CW\*(C`sub\*(C'\fR se sont produits dans la me\*^me porte\*'e, probablement la porte\*'e du fichier. .PP .Vb 2 \& my $x = 10; \& sub bumpx { $x++ } .Ve .PP Un \f(CW\*(C`eval()\*(C'\fR, toutefois, peut voir les variables lexicales de la porte\*'e dans laquelle il est e\*'value\*', tant que les noms ne sont pas cache\*'s par des de\*'clarations a\*` l'inte\*'rieur de l'\f(CW\*(C`eval()\*(C'\fR lui\-me\*^me. Voir perlref. .IX Xref "eval, porte\*'e d'un" .PP La liste de parame\*`tres de \fImy()\fR peut e\*^tre affecte\*'e si on le de\*'sire, ce qui vous permet d'initialiser vos variables (si aucune valeur initiale n'est donne\*'e a\*` une variable particulie\*`re, celle-ci est cre\*'e\*' avec la valeur inde\*'finie). Ceci est utilise\*' couramment pour nommer les parame\*`tres d'entre\*'e d'un sous\-programme. Exemples\ : .PP .Vb 4 \& $arg = "fred"; # variable "globale" \& $n = cube_root(27); \& print "$arg thinks the root is $n\en"; \& fred thinks the root is 3 \& \& sub cube_root { \& my $arg = shift; # le nom n'importe pas \& $arg **= 1/3; \& return $arg; \& } .Ve .PP Le \f(CW\*(C`my\*(C'\fR est simplement un modificateur sur quelque chose que vous pourriez affecter. Donc lorsque vous affectez les variable dans sa liste d'arguments, le \f(CW\*(C`my\*(C'\fR ne change pas le fait que ces variables soient vues comme un scalaire ou un tableau. Donc .PP .Vb 2 \& my ($foo) = ; # FAUX ? \& my @FOO = ; .Ve .PP les deux fournissent un contexte de liste a\*` la partie droite, tandis que .PP .Vb 1 \& my $foo = ; .Ve .PP fournit un contexte scalaire. Mais ce qui suit ne de\*'clare qu'une seule variable\ : .PP .Vb 1 \& my $foo, $bar = 1; # FAUX .Ve .PP Cela a le me\*^me effet que .PP .Vb 2 \& my $foo; \& $bar = 1; .Ve .PP La variable de\*'clare\*'e n'est pas introduite (n'est pas visible) avant la fin de l'instruction courante. Ainsi, .PP .Vb 1 \& my $x = $x; .Ve .PP peut e\*^tre utilise\*' pour initialiser une nouvelle variable \f(CW$x\fR avec la valeur de l'ancienne \f(CW$x\fR, et l'expression .PP .Vb 1 \& my $x = 123 and $x == 123 .Ve .PP est fausse a\*` moins que l'ancienne variable \f(CW$x\fR ait la valeur \f(CW123\fR. .PP Les porte\*'es lexicales de structures de contro\*^le ne sont pas pre\*'cise\*'ment lie\*'es aux accolades qui de\*'limitent le bloc qu'elles contro\*^lent ; les expressions de contro\*^le font aussi partie de cette porte\*'e. Ainsi, dans la boucle .PP .Vb 5 \& while (my $line =<>) { \& $line = lc $line; \& } continue { \& print $line; \& } .Ve .PP la porte\*'e de \f(CW$line\fR s'e\*'tend a\*` partir de sa de\*'claration et sur tout le reste de la boucle (y compris la clause \f(CW\*(C`continue\*(C'\fR), mais pas au\-dela\*`. De fac\*,on similaire, dans la conditionnelle .PP .Vb 8 \& if ((my $answer = ) =~ /^yes$/i) { \& user_agrees(); \& } elsif ($answer =~ /^no$/i) { \& user_disagrees(); \& } else { \& chomp $answer; \& die "'$answer' is neither 'yes' nor 'no'"; \& } .Ve .PP la porte\*'e de \f(CW$answer\fR s'e\*'tend a\*` partir de sa de\*'claration et sur tout le reste de la conditionnelle, y compris les clauses \f(CW\*(C`elsif\*(C'\fR et \f(CW\*(C`else\*(C'\fR, s'il y en a, mais pas au\-dela\*`. Voir \*(L"Instructions simples\*(R" in perlsyn pour plus d'informations sur la porte\*'e des variables dans des instructions avec modificateurs. .PP La boucle \f(CW\*(C`foreach\*(C'\fR a pour de\*'faut de donner une porte\*'e dynamiquement a sa variable d'index a\*` la manie\*`re de \f(CW\*(C`local\*(C'\fR. Toutefois, si la variable d'index est pre\*'fixe\*'e par le mot\-cle\*' \f(CW\*(C`my\*(C'\fR, ou s'il existe de\*'ja\*` un lexical ayant ce nom dans la porte\*', alors un nouveau lexical est cre\*'e\*' a\*` la place. Ainsi dans la boucle .IX Xref "foreach for" .PP .Vb 3 \& for my $i (1, 2, 3) { \& some_function(); \& } .Ve .PP la porte\*'e de \f(CW$i\fR s'e\*'tend jusqu'a\*` la fin de la boucle, rendant la valeur de \f(CW$i\fR inaccessible dans \f(CW\*(C`some_function()\*(C'\fR. .IX Xref "foreach for" .PP Certains utilisateurs pourraient de\*'sirer encourager l'usage de variables a\*` porte\*'e lexicale. Comme aide pour intercepter les utilisations implicites de variables de paquetage, qui sont toujours globales, si vous dites .PP .Vb 1 \& use strict 'vars'; .Ve .PP alors toute variable mentionne\*'e a\*` partir de la\*` jusqu'a\*` la fin du bloc doit soit se re\*'fe\*'rer a\*` une variable lexicale, soit e\*^tre pre\*'de\*'clare\*'e via \f(CW\*(C`our\*(C'\fR ou \f(CW\*(C`use vars\*(C'\fR, soit encore e\*^tre totalement qualifie\*'e avec le nom du paquetage. Autrement, une erreur de compilation se produit. Un bloc interne pourrait contrer ceci par \f(CW\*(C`no strict \&'vars'\*(C'\fR. .PP Un \f(CW\*(C`my\*(C'\fR a un effet a\*` la fois a\*` la compilation et lors de l'exe\*'cution. Lors de la compilation, le compilateur le remarque. La principale utilite\*' de ceci est de faire taire \f(CW\*(C`use strict 'vars'\*(C'\fR, mais c'est aussi essentiel pour la ge\*'ne\*'ration de fermetures telle que de\*'taille\*'e dans perlref. L'initialisation effective est toutefois retarde\*'e jusqu'a\*` l'exe\*'cution, de fac\*,on a\*` ce qu'elle soit exe\*'cute\*'e au moment approprie\*', par exemple a\*` chaque fois qu'une boucle traverse\*'e. .PP Les variables de\*'clare\*'es avec \f(CW\*(C`my\*(C'\fR ne font pas partie d'un paquetage et ne sont par conse\*'quent jamais totalement qualifie\*'e avec le nom du paquetage. En particulier, vous n'avez pas le droit d'essayer de rendre lexicale une variable de paquetage (ou toute autre variable globale)\ : .PP .Vb 2 \& my $pack::var; # ERREUR ! Syntaxe Ille\*'gale \& my $_; # aussi ille\*'gal (pour le moment) .Ve .PP En fait, une variable dynamique (aussi connue sous le nom de variable de paquetage ou variable globale) est toujours accessible en utilisant la notation totalement qualifie\*'e \f(CW\*(C`::\*(C'\fR me\*^me lorsqu'un lexical de me\*^me nom est lui aussi visible\ : .PP .Vb 4 \& package main; \& local $x = 10; \& my $x = 20; \& print "$x and $::x\en"; .Ve .PP Ceci affichera \f(CW20\fR et \f(CW10\fR. .PP Vous pouvez de\*'clarer les variables \f(CW\*(C`my\*(C'\fR dans la porte\*'e extre\*^me d'un fichier pour cacher tous ces identifants du monde exte\*'rieur a\*` ce fichier. Cela est similaire en esprit aux variables statiques de C quand elles sont utilise\*'es au niveau du fichier. Faire cela avec un sous-programme requiert l'usage d'une fermeture (une fonction anonyme qui acce\*`de aux lexicaux qui l'entourent). Si vous voulez cre\*'er un sous-programme prive\*' qui ne peut pas e\*^tre appele\*' en-dehors de ce bloc, il peut de\*'clarer une variable lexicale conenant une re\*'fe\*'rence anonyme de sous-programme\ : .PP .Vb 3 \& my $secret_version = '1.001\-beta'; \& my $secret_sub = sub { print $secret_version }; \& &$secret_sub(); .Ve .PP Tant que la re\*'fe\*'rence n'est jamais renvoye\*'e par aucune fonction du module, aucun module exte\*'rieur ne peut voir le sous\-programme, car son nom n'est dans la table de symboles d'aucun paquetage. Souvenez-vous qu'il n'est jamais \fI\s-1VRAIMENT\s0\fR appele\*' \f(CW$some_pack::secret_version\fR ou quoi que ce soit ; c'est juste \f(CW$secret_version\fR, non qualifie\*' et non qualifiable. .PP Ceci ne fonctionne pas avec les me\*'thodes d'objets, toutefois ; toutes les me\*'thodes d'objets doivent se trouver dans la table de symboles d'un paquetage quelconque pour e\*^tre trouve\*'es. Voir \*(L"Mode\*`les de Fonctions\*(R" in perlref pour une me\*'thode permettant de contourner ceci. .Sh "Variables prive\*'es persistantes" .IX Xref "statique variable persistante variable statique fermeture" .IX Subsection "Variables prive'es persistantes" Le fait qu'une variable lexicale ait une porte\*'e lexicale (aussi appele\*'e statique) e\*'gale au bloc qui la contient, a\*` l'\f(CW\*(C`eval\*(C'\fR, ou au \&\s-1FICHIER\s0 \f(CW\*(C`do\*(C'\fR, ne veut pas dire que cela fonctionne a\*` l'inte\*'rieur d'une fonction comme une variable statique en C. Cela marche pluto\*^t comme une variable auto de C, mais avec un nettoyage de la me\*'moire (un rammasse\-miettes) implicite. .PP Contrairement aux variables locales en C ou en \*(C+, les variables lexicales de Perl ne sont pas ne\*'cessairement recycle\*'es juste parce qu'on est sorti de leur porte\*'e. Si quelque chose de plus permanent est toujours conscient du lexical, il restera. Tant que quelque chose d'autre fait re\*'fe\*'rence au lexical, ce lexical ne sera pas libe\*'re\*' \&\*(-- ce qui est comme il se doit. Vous ne voudriez pas que la me\*'moire soit libe\*'re\*'e tant que vous n'avez pas fini de l'utiliser, ou garde\*'e lorsque vous en avez termine\*'. Le ramasse-miette automatique s'occupe de cela pour vous. .PP Ceci veut dire que vous pouvez passer en retour ou sauver des re\*'fe\*'rences a\*` des variables lexicales, tandis que retourner un pointeur sur un auto en C est une grave erreur. Cela nous donne aussi un moyen de simuler les variables statiques de fonctions C. Voici un me\*'canisme donnant a\*` une fonction des variables prive\*'es de porte\*'e lexicale ayant une dure\*'e de vie statique. Si vous de\*'sirez cre\*'er quelque chose ressemblant aux vatiables statiques de C, entourez juste toute la fonction d'un niveau de bloc supple\*'mentaire, et mettez la variable statique hors de la fonction mais dans le bloc. .PP .Vb 9 \& { \& my $secret_val = 0; \& sub gimme_another { \& return ++$secret_val; \& } \& } \& # $secret_val devient de\*'sormais impossible a\*` atteindre pour le \& # monde exte\*'rieur, mais garde sa valeur entre deux appels a\*` \& # gimme_another .Ve .PP Si cette fonction est charge\*'e par \f(CW\*(C`require\*(C'\fR ou \f(CW\*(C`use\*(C'\fR depuis un fichier se\*'pare\*', alors cela marchera probablement tre\*`s bien. Si tout se trouve dans le programme principal, vous devrez vous arranger pour que le \f(CW\*(C`my\*(C'\fR soit exe\*'cute\*' to\*^t, soit en mettant tout le bloc avant votre programme principal, ou, de pre\*'fe\*'rence, en plac\*,ant simplement un \&\f(CW\*(C`BEGIN\*(C'\fR devant lui pour vous assurer qu'il soit exe\*'cute\*'e avant que votre programme ne de\*'marre\ : .PP .Vb 6 \& BEGIN { \& my $secret_val = 0; \& sub gimme_another { \& return ++$secret_val; \& } \& } .Ve .PP Voir \*(L"\s-1BEGIN\s0, \s-1CHECK\s0, \s-1INIT\s0 et \s-1END\s0\*(R" in perlmod pour en savoir plus sur la mises en oeuvre des blocks spe\*'ciaux \f(CW\*(C`BEGIN\*(C'\fR, \f(CW\*(C`CHECK\*(C'\fR, \f(CW\*(C`INIT\*(C'\fR et \&\f(CW\*(C`END\*(C'\fR. .PP S'ils sont de\*'clare\*'s au niveau de la plus grande porte\*'e (celle du fichier), alors les lexicaux fonctionnent un peu comme les variables statiques de fichier en C. Ils sont disponibles pour toutes les fonctions de\*'clare\*'es en dessous d'eux dans le me\*^me fichier, mais sont inaccessibles hors du fichier. Cette strate\*'gie est parfois utilise\*' dans les modules pour cre\*'er des variables prive\*'es que la totalite\*' du module peut voir. .Sh "Valeurs temporaires via \fIlocal()\fP" .IX Subsection "Valeurs temporaires via local()" .IX Xref "local porte\*'e dynamique dynamique, porte\*'e variable locale variable temporaire" .PP \&\fB\s-1AVERTISSEMENT\s0\fR\ : en ge\*'ne\*'ral, vous devriez utiliser \f(CW\*(C`my\*(C'\fR au lieu de \&\f(CW\*(C`local\*(C'\fR, parce que c'est plus rapide et plus su\*^r. Les exceptions a\*` cela incluent les variables globales dont le nom est un caracte\*`re de ponctuation, les handles de fichier globaux et les formats globaux et la manipulation directe de la table de symboles de Perl. On utilise \&\f(CW\*(C`local\*(C'\fR lorsqu'on souhaite que la valeur courante d'une variable soit visible par les sous-programmes appele\*'s. .PP Synopsis\ : .PP .Vb 1 \& # local\-isation de valeurs \& \& local $foo; # rend $foo dynamiquement locale \& local (@wid, %get); # rend locales toutes les variables d'une liste \& local $foo = "flurp"; # rend $foo dynamique, et l'initialise \& local @oof = @bar; # rend @oof dynamique, et l'initialise \& \& local $hash{key} = "val"; # rend local la valeur lie\*' a\*` cette cle\*' \& local ($cond ? $v1 : $v2); # la plupart des types de lvalues \& # acceptent la local\-isation \& \& # local\-isation de symboles \& \& local *FH; # rend locales $FH, @FH, %FH, &FH... \& local *merlyn = *randal; # maintenant $merlyn est vraiment $randal, \& # @merlyn est vraiment @randal, etc. \& local *merlyn = 'randal'; # IDEM : 'randal' est promu *randal \& local *merlyn = \e$randal; # alias juste $merlyn, pas @merlyn etc .Ve .PP Un \f(CW\*(C`local()\*(C'\fR modifie ses variables liste\*'es pour qu'elle soient \&\*(L"locales\*(R" au bloc courant, a\*` l'\f(CW\*(C`eval\*(C'\fR, ou au \s-1FICHIER\s0 \f(CW\*(C`do\*(C'\fR \*(-- et a\*` \&\fItout sous-programme appele\*' depuis l'inte\*'rieur de ce bloc\fR. Un \&\f(CW\*(C`local()\*(C'\fR donne juste des valeurs temporaires aux variables globales (au paquetage). Il ne cre\*'e \fIpas\fR une variable locale. Ceci est connu sous le nom de porte\*'e dynamique. La porte\*'e lexicale est cre\*'e\*' par \&\f(CW\*(C`my\*(C'\fR, qui fonctionne plus comme les de\*'clarations auto de C. .PP Diffe\*'rents types de lvalues peuvent e\*^tre localise\*'s\ : les e\*'le\*'ments ou les tranches de tableaux ou de tables de hachage, e\*'ventuellement de manie\*`re conditionnelle (dans la mesure ou\*` le re\*'sultat est bien localisable), et les re\*'fe\*'rences symboliques. Comme pour de simples variables, cela cre\*'e de nouvelles valeurs avec une porte\*'e dynamqiue. .PP Si plus d'une variable est fournie a\*` \f(CW\*(C`local\*(C'\fR, elles doivent e\*^tre place\*'es entre parenthe\*`ses. Cet ope\*'rateur fonctionne en sauvegardant les valeurs courantes de ces variables dans sa liste d'arguments sur une pile cache\*'e et les restaure a\*` la sortie du bloc, du sous-programme ou de l'eval. Ceci veut dire que les sous-programmes appele\*'s peuvent aussi re\*'fe\*'rencer les variables locales, mais pas les globales. La liste d'arguments peut e\*^tre affecte\*'e si l'on veut, ce qui vous permet d'initialiser vos variables locales (si aucun initialiseur n'est donne\*' pour une variable locale particulie\*`re, elle est cre\*'e\*'e avec la valeur inde\*'finie). .PP Puisque \f(CW\*(C`local\*(C'\fR est une commande re\*'alise\*'e lors de la phase d'exe\*'cution, elle est donc exe\*'cute\*'e chaque fois que l'on traverse une boucle. Par conse\*'quent il est toujours plus efficace de localiser vos variables en dehors de la boucle. .PP \fINote grammatical sur \fIlocal()\fI\fR .IX Xref "contexte local" .IX Subsection "Note grammatical sur local()" .PP Un \f(CW\*(C`local\*(C'\fR est simplement un modificateur d'une expression donnant une lvalue. Lorsque vous affectez une variable \f(CW\*(C`local\*(C'\fRise\*'e, le \&\f(CW\*(C`local\*(C'\fR ne change pas selon que sa liste est vue comme un scalaire ou un tableau. Donc .PP .Vb 2 \& local($foo) = ; \& local @FOO = ; .Ve .PP fournissent tous les deux un contexte de liste a\*` la partie droite, tandis que .PP .Vb 1 \& local $foo = ; .Ve .PP fournit un contexte scalaire. .PP \fILocalisation des variables spe\*'ciales\fR .IX Xref "variables spe\*'ciales, localisation localisation des variables spe\*'ciales" .IX Subsection "Localisation des variables spe'ciales" .PP Si vous localisez une variable spe\*'ciale, vous lui donnez une nouvelle valeur mais sans lui faire perdre ses fonctionnalite\*'s magiques. Cela signifie que tous les effets secondaires de cette magie ont lieu avec cette nouvelle valeur. .PP Cela permet le fonctionnement d'un code tel que celui-ci\ : .PP .Vb 2 \& # Lit tout le contenu de FILE dans $slurp \& { local $/ = undef; $slurp = ; } .Ve .PP Notez, en revanche, que cela empe\*^che la localisation de certaines variables. Par exemple, l'instruction suivante de\*'clenchera, dans perl 5.9.0, un appel a\*` 'die' avec l'erreur \fIModification of a read-only value attempted\fR puisque \f(CW$1\fR est une variable magique en lecture seule\ : .PP .Vb 1 \& local $1 = 2; .Ve .PP De manie\*`re similaire mais moins e\*'vidente, le code suivant de\*'clenchera un 'die' en perl 5.9.0\ : .PP .Vb 5 \& sub f { local $_ = "foo"; print } \& for ($1) { \& # now $_ is aliased to $1, thus is magic and readonly \& f(); \& } .Ve .PP Voir la section suivante pour savoir comment palier cela. .PP \&\fB\s-1ATTENTION\s0\fR\ : la localisation de tableaux ou de tables de hachage lie\*'s (par \fItie()\fR) ne fonctionne pas comme cela. Cela sera corrige\*' dans une prochaine version de Perl. En attendant, e\*'vitez de localiser des tableaux ou des tables de hachage lie\*'s (la localistion de e\*'le\*'ments individuels fonctionnent). Voir \*(L"Localisation de tableaux et de tables de hachage lie\*'s (par \fItie()\fR)\*(R" in perl58delta pour plus de de\*'tails. .IX Xref "local, tie" .PP \fILocalisation de globs\fR .IX Xref "local, glob glob" .IX Subsection "Localisation de globs" .PP La construction .PP .Vb 1 \& local $name; .Ve .PP cre\*'e une nouvelle entre\*'e dans la table de symbole associe\*' au glob \&\f(CW\*(C`name\*(C'\fR dans le paquetage courant. Cela signifie que toutes les variables attache\*'es a\*` cette entre\*'e ($name, \f(CW@name\fR, \f(CW%name\fR, &name et le handle de fichier \f(CW\*(C`name\*(C'\fR) sont dynamiquement re\*'initialise\*'es. .PP En particulier, si vous voulez une nouvelle valeur pour le scalaire par de\*'faut \f(CW$_\fR, en e\*'vitant le proble\*`me potentiel e\*'voque\*' plus haut lorsque \f(CW$_\fR e\*'tait attache\*' a\*` une valeur magique. vous devriez utiliser \&\f(CW\*(C`local *_\*(C'\fR au lieu de \f(CW\*(C`local $_\*(C'\fR. .PP \fILocalisation des e\*'le\*'ments d'un type compose\*'\fR .IX Xref "local, type compose\*' local, e\*'le\*'ment d'un tableau local, e\*'le\*'ment d'une table de hachage" .IX Subsection "Localisation des e'le'ments d'un type compose'" .PP Une note sur \f(CW\*(C`local()\*(C'\fR et les types compose\*'s est ne\*'cessaire. Quelque chose comme \f(CW\*(C`local(%foo)\*(C'\fR fonctionne en plac\*,ant temporairement un hachage tout neuf dans la table des symboles. L'ancien hachage est mis de co\*^te\*', mais est cache\*' \*(L"derrie\*`re\*(R" le nouveau. .PP Ceci signifie que l'ancienne variable est comple\*`tement invisible via la table des symboles (i.e. l'entre\*'e de hachage dans le typeglob \&\f(CW*foo\fR) pendant toute la dure\*'e de la porte\*'e dynamique dans laquelle le \f(CW\*(C`local()\*(C'\fR a e\*'te\*' rencontre\*'. Cela a pour effet de permettre d'occulter temporairement toute magie sur les types compose\*'s. Par exemple, ce qui suit alte\*`rera brie\*`vement un hachage lie\*' a\*` une autre imple\*'mentation\ : .PP .Vb 12 \& tie %ahash, 'APackage'; \& [...] \& { \& local %ahash; \& tie %ahash, 'BPackage'; \& [.. le code appele\*' verra %ahash lie\*' a\*` 'BPackage'..] \& { \& local %ahash; \& [..%ahash est une hachage normal (non lie\*') ici..] \& } \& } \& [..%ahash revient a\*` sa nature lie\*'e initiale..] .Ve .PP Autre exemple, une imple\*'mentation personnelle de \f(CW%ENV\fR pourrait avoir l'air de ceci\ : .PP .Vb 6 \& { \& local %ENV; \& tie %ENV, 'MyOwnEnv'; \& [..faites vos propres manipulations fantaisistes de %ENV ici..] \& } \& [..comportement normal de %ENV ici..] .Ve .PP Il vaut aussi la peine de prendre un moment pour expliquer ce qui se passe lorsque vous \f(CW\*(C`local\*(C'\fRisez un membre d'un type compose\*' (i.e. un e\*'le\*'ment de tableau ou de hachage). Dans ce cas, l'e\*'le\*'ment est \&\f(CW\*(C`local\*(C'\fRise\*' \fIpar son nom\fR. Cela veut dire que lorsque la porte\*'e du \&\f(CW\*(C`local()\*(C'\fR se termine, la valeur sauve\*'e sera restaure\*'e dans l'e\*'le\*'ment du hachage dont la cle\*' a e\*'te\*' nomme\*'e dans le \f(CW\*(C`local()\*(C'\fR, ou dans l'e\*'le\*'ment du tableau dont l'index a e\*'te\*' nomme\*' dans le \f(CW\*(C`local()\*(C'\fR. Si cet e\*'le\*'ment a e\*'te\*' efface\*' pendant que le \f(CW\*(C`local()\*(C'\fR faisait effet (e.g. par un \f(CW\*(C`delete()\*(C'\fR dans un hachage ou un \f(CW\*(C`shift()\*(C'\fR d'un tableau), il reprendra vie, e\*'tendant potentiellement un tableau et remplissant les e\*'le\*'ments interme\*'diaires avec \f(CW\*(C`undef\*(C'\fR. Par exemple, si vous dites .PP .Vb 10 \& %hash = ( 'This' => 'is', 'a' => 'test' ); \& @ary = ( 0..5 ); \& { \& local($ary[5]) = 6; \& local($hash{'a'}) = 'drill'; \& while (my $e = pop(@ary)) { \& print "$e . . .\en"; \& last unless $e > 3; \& } \& if (@ary) { \& $hash{'only a'} = 'test'; \& delete $hash{'a'}; \& } \& } \& print join(' ', map { "$_ $hash{$_}" } sort keys %hash),".\en"; \& print "The array has ",scalar(@ary)," elements: ", \& join(', ', map { defined $_ ? $_ : 'undef' } @ary),"\en"; .Ve .PP Perl affichera .PP .Vb 5 \& 6 . . . \& 4 . . . \& 3 . . . \& This is a test only a test. \& The array has 6 elements: 0, 1, 2, undef, undef, 5 .Ve .PP Le comportement de \fIlocal()\fR sur des membres inexistants de types composites est sujet a\*` changements a\*` l'avenir. .Sh "Lvalue et sous-programme" .IX Xref "lvalue sous-programme, lvalue" .IX Subsection "Lvalue et sous-programme" \&\fB\s-1AVERTISSEMENT\s0\fR\ : les sous-programmes en partie gauche (en lvalue) sont encore expe\*'rimentaux et leur imple\*'mentation est sujette a\*` changements dans les futures versions de Perl. .PP Il est possible de retourner une valeur modifiable depuis un sous\-programme. Pour ce faire, vous devez de\*'clarer que le sous-programme retourne une lvalue. .PP .Vb 5 \& my $val; \& sub canmod : lvalue { \& # return $val; cela ne fonction pas, ne dites pas "return" \& $val; \& } \& \& sub nomod { \& $val; \& } \& \& canmod() = 5; # modifie $val \& nomod() = 5; # ERREUR .Ve .PP Le contexte scalaire ou de liste pour le sous-programme et la partie droite de l'affectation est de\*'termine\*' comme si l'appel au sous-programme e\*'tait remplace\*' par un scalaire. Par exemple, si l'on conside\*`re\ : .PP .Vb 1 \& data(2,3) = get_data(3,4); .Ve .PP Les deux sous-programmes sont appele\*'es ici dans un contexte scalaire, tandis que dans\ : .PP .Vb 1 \& (data(2,3)) = get_data(3,4); .Ve .PP et dans\ : .PP .Vb 1 \& (data(2),data(3)) = get_data(3,4); .Ve .PP tous les sous-programmes sont appele\*'s dans un contexte de liste. .IP "Les sous-programmes lvalue sont expe\*'rimentaux" 4 .IX Item "Les sous-programmes lvalue sont expe'rimentaux" Cela semble pratique mais il y a plusieurs raisons pour rester circonspect. .Sp Vous ne devez pas utiliser le mot\-cle\*' return et vous devez passez la valeur de sortie avant qu'elle soit hors de porte\*'e (voir le commentaire dans l'exemple plus haut). Ce n'est pas habituellement un proble\*`me mais cela empe\*^che tout de me\*^me un return explicite dans une boucle qui est pourtant parfois bien pratique. .Sp Cela ne respecte pas l'encapsulation. Un mutateur normal ve\*'rifie la valeur fournie avant de l'affecter a\*` l'attribut qu'il prote\*`ge. Un sous-programme lvalue ne permet pas cela. Conside\*'rez le code suivant\ : .Sp .Vb 1 \& my $some_array_ref = []; # prote\*'ge\*' par un mutateur ?? \& \& sub set_arr { # mutateur normal \& my $val = shift; \& die("expected array, you supplied ", ref $val) \& unless ref $val eq 'ARRAY'; \& $some_array_ref = $val; \& } \& sub set_arr_lv : lvalue { # mutateur par lvalue \& $some_array_ref; \& } \& \& # set_arr_lv ne peut pas empe\*^cher cela ! \& set_arr_lv() = { a => 1 }; .Ve .Sh "Passage d'entre\*'es de table de symbole (typeglobs)" .IX Xref "typeglob *" .IX Subsection "Passage d'entre'es de table de symbole (typeglobs)" \&\fB\s-1AVERTISSEMENT\s0\fR\ : le me\*'canisme de\*'crit dans cette section e\*'tait a\*` l'origine la seule fac\*,on de simuler un passage par re\*'fe\*'rence dans les anciennes versions de Perl. Me\*^me si cela fonctionne toujours tre\*`s bien dans les version modernes, le nouveau me\*'canisme de re\*'fe\*'rencement est ge\*'ne\*'ralement plus facile a\*` utiliser. Voir plus bas. .PP Parfois, vous ne voulez pas passer la valeur d'un tableau a\*` un sous-programme mais pluto\*^t son nom, pour que le sous-programme puisse modifier sa copie globale pluto\*^t que de travailler sur une copie locale. En perl, vous pouvez vous re\*'fe\*'rer a\*` tous les objets d'un nom particulier en pre\*'fixant ce nom par une e\*'toile\ : \f(CW*foo\fR. Cela est souvent connu sous le nom de \*(L"typeglob\*(R", car l'e\*'toile devant peut e\*^tre conc\*,ue comme un caracte\*`re ge\*'ne\*'rique correspondant a\*` tous les dro\*^les de caracte\*`res pre\*'fixant les variables et les sous-programmes et le reste. .PP Lorsqu'il est e\*'value\*', le typeglob produit une valeur scalaire qui repre\*'sente tous les objets portant ce nom, y compris tous les handles de fichiers, les formats, ou les sous\-programmes. Quand on l'affecte, le nom mentionne\*' se re\*'fe\*`re alors a\*` la valeur \f(CW\*(C`*\*(C'\fR qui lui a e\*'te\*' affecte\*'e, quelle qu'elle soit. Exemple\ : .PP .Vb 8 \& sub doubleary { \& local(*someary) = @_; \& foreach $elem (@someary) { \& $elem *= 2; \& } \& } \& doubleary(*foo); \& doubleary(*bar); .Ve .PP Les scalaires sont de\*'ja\*` passe\*'s par re\*'fe\*'rence, vous pouvez donc modifier les arguments scalaires sans utiliser ce me\*'canisme en vous re\*'fe\*'rant explicitement a\*` \f(CW$_[0]\fR, etc. Vous pouvez modifier tous les e\*'le\*'ments d'un tableau en passant tous les e\*'le\*'ments comme des scalaires, mais vous devez utiliser le me\*'canisme \f(CW\*(C`*\*(C'\fR (ou le me\*'canisme de re\*'fe\*'rencement e\*'quivalent) pour effectuer des \f(CW\*(C`push\*(C'\fR, des \f(CW\*(C`pop\*(C'\fR, ou changer la taille d'un tableau. Il sera certainement plus rapide de passer le typeglob (ou la re\*'fe\*'rence). .PP Me\*^me si vous ne voulez pas modifier un tableau, ce me\*'canisme est utile pour passer des tableaux multiples dans une seule \s-1LIST\s0, car normalement le me\*'canisme \s-1LIST\s0 fusionnera toutes les valeurs de tableaux et vous ne pourrez plus en extraire les tableaux individuels. Pour plus de de\*'tails sur les typeglobs, voir \&\*(L"Typeglobs et handles de fichiers\*(R" in perldata. .Sh "Quand faut-il encore utiliser \fIlocal()\fP" .IX Subsection "Quand faut-il encore utiliser local()" Malgre\*' l'existence de \f(CW\*(C`my\*(C'\fR, il y a encore trois endroits ou\*` l'ope\*'rateur \f(CW\*(C`local\*(C'\fR brille toujours. En fait, en ces trois endroits, vous \fIdevez\fR utiliser \f(CW\*(C`local\*(C'\fR a\*` la place de \f(CW\*(C`my\*(C'\fR. .IP "1." 4 Vous avez besoin de donner une valeur temporaire a\*` une variable globale, en particulier \f(CW$_\fR. .Sp Les variables globales, comme \f(CW@ARGV\fR ou les variables de ponctuation, doivent e\*^tre \f(CW\*(C`local\*(C'\fRise\*'es avec \f(CW\*(C`local()\*(C'\fR. Ce bloc lit dans \fI/etc/motd\fR, et le de\*'coupe en morceaux, se\*'pare\*'s par des lignes de signes e\*'gal, qui sont place\*'s dans \f(CW@Fields\fR. .Sp .Vb 6 \& { \& local @ARGV = ("/etc/motd"); \& local $/ = undef; \& local $_ = <>; \& @Fields = split /^\es*=+\es*$/; \& } .Ve .Sp Il est important en particulier de \f(CW\*(C`local\*(C'\fRiser \f(CW$_\fR dans toute routine qui l'affecte. Surveillez les affectations implicites dans les conditionnelles \f(CW\*(C`while\*(C'\fR. .IP "2." 4 Vous avez besoin de cre\*'er un handle de fichier ou de re\*'pertoire local, ou une fonction locale. .Sp Une fonction ayant besoin de son propre handle de fichier doit utiliser \f(CW\*(C`local()\*(C'\fR sur le typeglob complet. Ceci peut e\*^tre utilise\*' pour cre\*'er de nouvelles entre\*'es dans la table des symboles\ : .Sp .Vb 6 \& sub ioqueue { \& local (*READER, *WRITER); # pas my ! \& pipe (READER, WRITER) or die "pipe: $!"; \& return (*READER, *WRITER); \& } \& ($head, $tail) = ioqueue(); .Ve .Sp Voir le module Symbol pour une fac\*,on de cre\*'er des entre\*'es de table de symboles anonymes. .Sp Puisque l'affectation d'une re\*'fe\*'rence a\*` un typeglob cre\*'e un alias, ceci peut e\*^tre utilise\*' pour cre\*'er ce qui est effectivement une fonction locale, ou au moins un alias local. .Sp .Vb 8 \& { \& local *grow = \e&shrink; # seulement jusqu'a\*` la fin de \& # l'existence de ce bloc \& grow(); # appelle en fait shrink() \& move(); # si move() grandit, il re\*'tre\*'cit \& # aussi \& } \& grow(); # re\*'cupe\*`re le vrai grow() .Ve .Sp Voir \*(L"Mode\*`les de fonctions\*(R" in perlref pour plus de de\*'tails sur la manipulation des fonctions par leur nom de cette manie\*`re. .IP "3." 4 Vous voulez changer temporairement un seul e\*'le\*'ment d'un tableau ou d'un hachage. .Sp Vous pouvez \f(CW\*(C`local\*(C'\fRiser juste un e\*'le\*'ment d'un aggre\*'gat. Habituellement, cela est fait dynamiquement\ : .Sp .Vb 5 \& { \& local $SIG{INT} = 'IGNORE'; \& funct(); # impossible a\*` interrompre \& } \& # la possibilite\*' d'interrompre est restaure\*'e ici .Ve .Sp Mais cela fonctionne aussi sur les aggre\*'gats de\*'clare\*'s lexicalement. Avant la version 5.005, cette ope\*'ration pouvait parfois mal se conduire. .Sh "Passage par re\*'fe\*'rence" .IX Xref "passage par re\*'fe\*'rence re\*'fe\*'rence, passage par re\*'fe\*'rence" .IX Subsection "Passage par re'fe'rence" Si vous voulez passer plus d'un tableau ou d'un hachage a\*` une fonction \&\*(-- ou les renvoyer depuis elle \*(-- de fac\*,on qu'ils gardent leur inte\*'grite\*', vous allez devoir alors utiliser un passage par re\*'fe\*'rence explicite. Avant de faire cela, vous avez besoin de comprendre les re\*'fe\*'rences telles qu'elles sont de\*'taille\*'es dans perlref. Cette section n'aura peut\-e\*^tre pas beaucoup de sens pour vous sans cela. .PP Voici quelques exemples simples. Tout d'abord, passons plusieurs tableaux a\*` une fonction puis faisons-lui faire des \f(CW\*(C`pop\*(C'\fR sur eux, et retourner une nouvelle liste de tous leurs derniers e\*'le\*'ments\ : .PP .Vb 1 \& @tailings = popmany ( \e@a, \e@b, \e@c, \e@d ); \& \& sub popmany { \& my $aref; \& my @retlist = (); \& foreach $aref ( @_ ) { \& push @retlist, pop @$aref; \& } \& return @retlist; \& } .Ve .PP Voici comment vous pourriez e\*'crire une fonction retournant une liste des cle\*'s apparaissant dans tous les hachages qu'on lui passe\ : .PP .Vb 10 \& @common = inter( \e%foo, \e%bar, \e%joe ); \& sub inter { \& my ($k, $href, %seen); # locals \& foreach $href (@_) { \& while ( $k = each %$href ) { \& $seen{$k}++; \& } \& } \& return grep { $seen{$_} == @_ } keys %seen; \& } .Ve .PP Jusque la\*`, nous utilisons juste le me\*'canisme normal de retour d'une liste. Que se passe-t-il si vous voulez passer ou retourner un hachage ? Eh bien, si vous n'utilisez que l'un d'entre eux, ou si vous ne voyez pas d'inconve\*'nient a\*` ce qu'ils soient concate\*'ne\*'s, alors la convention d'appel normale est valable, me\*^me si elle cou\*^te un peu cher. .PP C'est ici que les gens commencent a\*` avoir des proble\*`mes\ : .PP .Vb 3 \& (@a, @b) = func(@c, @d); \&ou \& (%a, %b) = func(%c, %d); .Ve .PP Cette syntaxe ne fonctionnera tout simplement pas. Elle de\*'finit juste \&\f(CW@a\fR ou \f(CW%a\fR et vide \f(CW@b\fR ou \f(CW%b\fR. De plus, la fonction n'a pas obtenu deux tableaux ou hachages se\*'pare\*'s\ : elle a eu une longue liste dans \f(CW@_\fR, comme toujours. .PP Si vous pouvez vous arranger pour que tout le monde re\*`gle cela par des re\*'fe\*'rences, cela fait du code plus propre, me\*^me s'il n'est pas tre\*`s joli a\*` regarder (phrase louche, \s-1NDT\s0). Voici une fonction qui prend deux re\*'fe\*'rences de tableau comme arguments et renvoit les deux e\*'le\*'ments de tableau dans l'ordre du nombre d'e\*'le\*'ments qu'ils contiennent\ : .PP .Vb 10 \& ($aref, $bref) = func(\e@c, \e@d); \& print "@$aref has more than @$bref\en"; \& sub func { \& my ($cref, $dref) = @_; \& if (@$cref > @$dref) { \& return ($cref, $dref); \& } else { \& return ($dref, $cref); \& } \& } .Ve .PP Il s'ave\*`re en fait que vous pouvez aussi faire ceci\ : .PP .Vb 10 \& (*a, *b) = func(\e@c, \e@d); \& print "@a has more than @b\en"; \& sub func { \& local (*c, *d) = @_; \& if (@c > @d) { \& return (\e@c, \e@d); \& } else { \& return (\e@d, \e@c); \& } \& } .Ve .PP Ici nous utilisons les typeglobs pour faire un aliasing de la table des symboles. C'est un peu subtile, toutefois, et en plus cela ne fonctionnera pas si vous utilisez des variables \f(CW\*(C`my\*(C'\fR, puisque seules les variables globales (et les \f(CW\*(C`local\*(C'\fRes en fait) sont dans la table des symboles. .PP Si vous passez des handles de fichiers, vous pouvez habituellement juste utiliser le typeglob tout seul, comme \f(CW*STDOUT\fR, mais les re\*'fe\*'rences de typeglobs fonctionnent aussi. Par exemple\ : .PP .Vb 5 \& splutter(\e*STDOUT); \& sub splutter { \& my $fh = shift; \& print $fh "her um well a hmmm\en"; \& } \& \& $rec = get_rec(\e*STDIN); \& sub get_rec { \& my $fh = shift; \& return scalar <$fh>; \& } .Ve .PP Si vous comptez ge\*'ne\*'rer de nouveau handles de fichiers, vous pourriez faire ceci. Faites attention de renvoyer juste le *FH tout seul, et pas sa re\*'fe\*'rence. .PP .Vb 5 \& sub openit { \& my $path = shift; \& local *FH; \& return open (FH, $path) ? *FH : undef; \& } .Ve .Sh "Prototypes" .IX Xref "prototype sous-programme, prototype" .IX Subsection "Prototypes" Perl supporte une sorte de ve\*'rification des arguments tre\*`s limite\*'e lors de la compilation, en utilisant le prototypage de fonction. Si vous de\*'clarez .PP .Vb 1 \& sub mypush (\e@@) .Ve .PP alors \f(CW\*(C`mypush()\*(C'\fR prendra ses arguments exactement comme \f(CW\*(C`push()\*(C'\fR le fait. La declaration de la fonction doit e\*^tre visible au moment de la compilation. Le prototype affecte seulement l'interpre\*'tation des appels nouveau style de la fonction, ou\*` le nouveau style est de\*'fini comme n'utilisant pas le caracte\*`re \f(CW\*(C`&\*(C'\fR. En d'autres termes, si vous l'appelez comme une fonction inte\*'gre\*'e, alors elle se comportera comme une fonction inte\*'gre\*'e. Si vous l'appelez comme un sous-programme a\*` l'ancienne mode, alors elle se comportera comme un sous-programme a\*` l'ancienne. La conse\*'quence naturelle de cette re\*`gle est que les prototypes n'ont pas d'influence sur les re\*'fe\*'rences de sous-programmes comme \f(CW\*(C`\e&foo\*(C'\fR ou sur les appels de sous-programmes indirects comme \&\f(CW\*(C`&{$subref}\*(C'\fR ou \f(CW\*(C`$subref\->()\*(C'\fR. .PP Les appels de me\*'thode ne sont pas non plus influence\*'s par les prototypes, car la fonction qui doit e\*^tre appele\*'e est inde\*'termine\*'e au moment de la compilation, puisque le code exact appele\*' de\*'pend de l'he\*'ritage. .PP Puisque l'intention de cette caracte\*'ristique est principalement de vous laisser de\*'finir des sous-programmes qui fonctionnent comme des commandes inte\*'gre\*'es, voici des prototypes pour quelques autres fonctions qui se compilent presque exactement comme les fonctions inte\*'gre\*'es correspondantes. .PP .Vb 1 \& De\*'clare\*'es en tant que Appele\*' comme \& \& sub mylink ($$) mylink $old, $new \& sub myvec ($$$) myvec $var, $offset, 1 \& sub myindex ($$;$) myindex &getstring, "substr" \& sub mysyswrite ($$$;$) mysyswrite $buf, 0, length($buf) \- $off, $off \& sub myreverse (@) myreverse $a, $b, $c \& sub myjoin ($@) myjoin ":", $a, $b, $c \& sub mypop (\e@) mypop @array \& sub mysplice (\e@$$@) mysplice @array, @array, 0, @pushme \& sub mykeys (\e%) mykeys %{$hashref} \& sub myopen (*;$) myopen HANDLE, $name \& sub mypipe (**) mypipe READHANDLE, WRITEHANDLE \& sub mygrep (&@) mygrep { /foo/ } $a, $b, $c \& sub myrand ($) myrand 42 \& sub mytime () mytime .Ve .PP Tout caracte\*`re de prototype pre\*'ce\*'de\*' d'une barre oblique inverse repre\*'sente un ve\*'ritable argument qui doit absolument commencer par ce caracte\*`re. La valeur passe\*'e comme partie de \f(CW@_\fR sera une re\*'fe\*'rence au ve\*'ritable argument passe\*' dans l'appel du sous\-programme, obtenue en appliquant \f(CW\*(C`\e\*(C'\fR a\*` cet argument. .PP Vous pouvez aussi transformer d'un seul coup en re\*'fe\*'rence a\*` plusieurs types d'argument en utilisant la notation \f(CW\*(C`\e[]\*(C'\fR\ : .PP .Vb 1 \& sub myref (\e[$@%&*]) .Ve .PP qui autorisera les appels suivant a\*` \fImyref()\fR\ : .PP .Vb 5 \& myref $var \& myref @array \& myref %hash \& myref &sub \& myref *glob .Ve .PP et le premier argument de \fImyref()\fR sera une re\*'fe\*'rence a\*` un scalaire, un tableau, une table de hachage, du code ou a\*` un glob. .PP Les caracte\*`res de prototype non pre\*'ce\*'de\*'s d'une barre oblique inverse ont une signification spe\*'ciale. Tout \f(CW\*(C`@\*(C'\fR ou \f(CW\*(C`%\*(C'\fR sans barre oblique inverse mange les arguments restants, et force un contexte de liste. Un argument repre\*'sente\*' par \f(CW\*(C`$\*(C'\fR force un contexte scalaire. Un \&\f(CW\*(C`&\*(C'\fR requiert un sous-programme anonyme, qui, s'il est passe\*' comme premier argument, ne requiert pas le mot\-cle\*' "\f(CW\*(C`sub\*(C'\fR" ni une virgule apre\*`s lui. Un \f(CW\*(C`*\*(C'\fR permet au sous-programme d'accepter un bareword, une constante, une expression scalaire, un typeglob, ou une re\*'fe\*'rence a\*` un typeglob a\*` cet emplacement. La valeur sera disponible pour le sous-programme soit comme un simple scalaire, soit (dans les deux derniers cas) comme une re\*'fe\*'rence au typeglob. Si vous de\*'sirez toujours convertir de tels arguments en re\*'fe\*'rence de typeglob, utilisez \fISymbol::qualify_to_ref()\fR ainsi\ : .PP .Vb 1 \& use Symbol 'qualify_to_ref'; \& \& sub foo (*) { \& my $fh = qualify_to_ref(shift, caller); \& ... \& } .Ve .PP Un point-virgule se\*'pare les arguments obligatoires des arguments optionnels. Il est redondant devant \f(CW\*(C`@\*(C'\fR ou \f(CW\*(C`%\*(C'\fR, qui engloutissent tout le reste. .PP Notez comment les trois derniers exemples dans la table ci-dessus sont traite\*'s spe\*'cialement par l'analyseur. \f(CW\*(C`mygrep()\*(C'\fR est compile\*' comme un ve\*'ritable ope\*'rateur de liste, \f(CW\*(C`myrand()\*(C'\fR comme un ve\*'ritable ope\*'rateur unaire avec une pre\*'ce\*'dence unaire identique a\*` celle de \f(CW\*(C`rand()\*(C'\fR, et \&\f(CW\*(C`mytime()\*(C'\fR est vraiment sans arguments, tout comme \&\f(CW\*(C`time()\*(C'\fR. C'est\-a\*`\-dire que si vous dites .PP .Vb 1 \& mytime +2; .Ve .PP Vous obtiendrez \f(CW\*(C`mytime() + 2\*(C'\fR, et pas \f(CWmytime(2)\fR, qui est la fac\*,on dont cela serait analyse\*' sans prototype. .PP Ce qui est inte\*'ressant avec \f(CW\*(C`&\*(C'\fR est que vous pouvez ge\*'ne\*'rer une nouvelle syntaxe gra\*^ce a\*` lui, pourvu qu'il soit en position initiale\ : .IX Xref "&" .PP .Vb 9 \& sub try (&@) { \& my($try,$catch) = @_; \& eval { &$try }; \& if ($@) { \& local $_ = $@; \& &$catch; \& } \& } \& sub catch (&) { $_[0] } \& \& try { \& die "phooey"; \& } catch { \& /phooey/ and print "unphooey\en"; \& }; .Ve .PP Cela affiche \f(CW"unphooey"\fR (Oui, il y a toujours des proble\*`mes non re\*'solus a\*` propos de la visibilite\*' de \f(CW@_\fR. J'ignore cette question pour le moment (Mais notez que si nous donnons une porte\*'e lexicale a\*` \&\f(CW@_\fR, ces sous-programmes anonymes peuvent agir comme des fermetures... (Mince, est-ce que ceci sonne un peu lispien ? (Peu importe))). .PP Et voici une re\*'imple\*'mentation de l'ope\*'rateur \f(CW\*(C`grep\*(C'\fR de Perl\ : .IX Xref "grep" .PP .Vb 8 \& sub mygrep (&@) { \& my $code = shift; \& my @result; \& foreach $_ (@_) { \& push(@result, $_) if &$code; \& } \& @result; \& } .Ve .PP Certaines personnes pre\*'fe\*'reraient des prototypes pleinement alphanume\*'riques. Les caracte\*`res alphanume\*'riques ont intentionnellement e\*'te\*' laisse\*'s hors des prototypes expresse\*'ment dans le but d'ajouter un jour futur des pareme\*`tres formels nomme\*'s. Le principal objectif du me\*'canisme actuel est de laisser les programmeurs de modules fournir de meilleurs diagnostics a\*` leurs utilisateurs. Larry estime que la notation est bien compre\*'hensible pour les programmeurs Perl, et que cela n'interfe\*`rera pas notablement avec le coeur du module, ni ne le rendra plus difficile a\*` lire. Le bruit sur la ligne est visuellement encapsule\*' dans une petite pilule facile a\*` avaler. .PP Si vous essayez d'utiliser des se\*'quences alphanume\*'riques dans un prototype, vous aurez droit a\*` un avertissement optionnel \- \*(L"Illegal character in prototype...\*(R". Malheureusement, les anciennes versions de Perl autorisaient l'utilisation de ce type de prototype tant que le de\*'but e\*'tait un prototype valide. L'avertissement actuel pourrait devenir une erreur fatale dans une future version de Perl lorsque la mejorite\*' du code errone\*' aura e\*'te\*' corrige\*'. .PP Il est probablement meilleur de prototyper les nouvelles fonctions, et de ne pas prototyper re\*'trospectivement les anciennes. C'est parce que vous devez e\*^tre particulie\*`rement pre\*'cautionneux avec les exigences silencieuses de la diffe\*'rence entre les contextes de liste et les contextes scalaires. Par exemple, si vous de\*'cidez qu'une fonction devrait prendre juste un parame\*`tre, comme ceci\ : .PP .Vb 4 \& sub func ($) { \& my $n = shift; \& print "you gave me $n\en"; \& } .Ve .PP et que quelqu'un l'a appele\*'e avec un tableau ou une expression retournant une liste\ : .PP .Vb 2 \& func(@foo); \& func( split /:/ ); .Ve .PP Alors vous venez juste de fournir un \f(CW\*(C`scalar\*(C'\fR automatique devant leurs arguments, ce qui peut e\*^tre plus que surprenant. L'ancien \&\f(CW@foo\fR qui avait l'habitude de ne contenir qu'une chose n'entre plus. A\*` la place, \f(CW\*(C`func()\*(C'\fR se voit maintenant passer un \f(CW1\fR ; c'est\-a\*`\-dire le nombre d'e\*'le\*'ments dans \f(CW@foo\fR. Et le \f(CW\*(C`split\*(C'\fR se voit appele\*' dans un contexte scalaire et commence a\*` gribouiller dans votre liste de parame\*`tres \f(CW@_\fR. Ai\*:e ! .PP Tout ceci est tre\*`s puissant, bien su\*^r, et devrait e\*^tre utilise\*' uniquement avec mode\*'ration pour rendre le monde meilleur. .Sh "Fonctions constantes" .IX Xref "constante" .IX Subsection "Fonctions constantes" Les fonctions ayant un prototype e\*'gal a\*` \f(CW\*(C`()\*(C'\fR sont des candidates potentielles a\*` l'insertion en ligne (inlining, \s-1NDT\s0). Si le re\*'sultat apre\*`s optimisation et repliement des constantes est soit une constante soir un scalaire de porte\*'e lexicale n'ayant pas d'autre re\*'fe\*'rence, alors il sera utilise\*' a\*` la place des appels a\*` la fonction faits sans \&\f(CW\*(C`&\*(C'\fR. Les appels re\*'alise\*'s en utilisant \f(CW\*(C`&\*(C'\fR ne sont jamais inse\*'re\*'s en ligne (Voir \fIconstant.pm\fR pour une fac\*,on aise\*'e de de\*'clarer la plupart des constantes). .PP Les fonctions suivantes seraient toutes inse\*'re\*'es en ligne\ : .PP .Vb 4 \& sub pi () { 3.14159 } # Pas exact, mais proche. \& sub PI () { 4 * atan2 1, 1 } # Aussi exact qu'il \& # puisse e\*^tre, et \& # inse\*'re\*' en ligne aussi ! \& \& sub ST_DEV () { 0 } \& sub ST_INO () { 1 } \& \& sub FLAG_FOO () { 1 << 8 } \& sub FLAG_BAR () { 1 << 9 } \& sub FLAG_MASK () { FLAG_FOO | FLAG_BAR } \& \& sub OPT_BAZ () { not (0x1B58 & FLAG_MASK) } \& \& sub N () { int(OPT_BAZ) / 3 } \& \& sub FOO_SET () { 1 if FLAG_MASK & FLAG_FOO } .Ve .PP En revanche, celles qui suivent ne pourront e\*^tre inse\*'re\*'es en ligne ; parce qu'elles contiennent des choses non constantes dans leur propre porte\*'e. .PP .Vb 1 \& sub foo_set () { if (FLAG_MASK & FLAG_FOO) { 1 } } \& \& sub baz_val () { \& if (OPT_BAZ) { \& return 23; \& } \& else { \& return 42; \& } \& } .Ve .PP Si vous rede\*'finissez un sous-programmes qui pouvait e\*^tre inse\*'re\*' en ligne, vous obtiendrez un avertissement formel (vous pouvez utiliser cet avertissement pour de\*'terminer si un sous-programme particulier est conside\*'re\*' comme constant ou pas). L'avertissement est conside\*'re\*' comme suffisamment se\*'ve\*`re pour ne pas e\*^tre optionnel, car les invocations pre\*'ce\*'demment compile\*'es de la fonction utiliseront toujours l'ancienne valeur de cette fonction. Si vous avez besoin de pouvoir rede\*'finir le sous\-programme, vous devez vous assurer qu'il n'est pas inse\*'re\*' en ligne, soit en abandonnant le prototype \f(CW\*(C`()\*(C'\fR (ce qui change la se\*'mantique de l'appel, donc prenez garde), soit en contrecarrant le me\*'canisme d'insertion d'une autre fac\*,on, comme par exemple .PP .Vb 3 \& sub not_inlined () { \& 23 if $]; \& } .Ve .Sh "Surcharges des fonctions pre\*'de\*'finies" .IX Xref "pre\*'de\*'finie fonction pre\*'de\*'finie surcharge CORE CORE::GLOBAL" .IX Subsection "Surcharges des fonctions pre'de'finies" Beaucoup de fonctions pre\*'de\*'finies peuvent e\*^tre surcharge\*'es, me\*^me si cela ne devrait e\*^tre essaye\*' qu'occasionnellement et pour une bonne raison. Typiquement, cela pourrait e\*^tre re\*'alise\*' par un paquetage essayant d'e\*'muler une fonctionnalite\*' pre\*'de\*'finie manquante sur un syste\*`me non Unix. .PP La surcharge ne peut e\*^tre re\*'alise\*'e qu'en important le nom depuis un module lors de la compilation \*(-- la pre\*'de\*'claration ordinaire n'est pas suffisante. Toutefois, le pragma \f(CW\*(C`use subs\*(C'\fR vous laisse, dans les faits, pre\*'de\*'clarer les sous-programmes via la syntaxe d'importation, et ces noms peuvent ensuite surcharger ceux qui sont pre\*'de\*'finis\ : .PP .Vb 3 \& use subs 'chdir', 'chroot', 'chmod', 'chown'; \& chdir $somewhere; \& sub chdir { ... } .Ve .PP Pour se re\*'fe\*'rer sans ambigui\*:te\*' a\*` la forme pre\*'de\*'finie, on peut faire pre\*'ce\*'der le nom pre\*'de\*'fini par le qualificateur de paquetage spe\*'ciale \&\f(CW\*(C`CORE::\*(C'\fR. Par exemple, le fait de dire \f(CW\*(C`CORE::open()\*(C'\fR se re\*'fe\*`re toujours a\*` la fonction pre\*'de\*'finie \f(CW\*(C`open()\*(C'\fR, me\*^me si le paquetage courant a importe\*' d'ailleurs un quelconque autre sous-programme appele\*' \&\f(CW\*(C`&open()\*(C'\fR. Me\*^me si cela a l'air d'un appel de fonction normal, ce n'en est pas un\ : vous ne pouvez pas en cre\*'er de re\*'fe\*'rence, telle que celles que l'incorrect \f(CW\*(C`\e&CORE::open\*(C'\fR pourrait en produire. .PP Les modules de bibliothe\*`que ne devraient en ge\*'ne\*'ral pas exporter de noms pre\*'de\*'finis comme \f(CW\*(C`open\*(C'\fR ou \f(CW\*(C`chdir\*(C'\fR comme partie de leur liste \&\f(CW@EXPORT\fR par de\*'faut, car ceux-ci pourraient s'infiltrer dans l'espace de noms de quelqu'un d'autre et changer la se\*'mantique de fac\*,on inattendue. A\*` la place, si le module ajoute ce nom a\*` \&\f(CW@EXPORT_OK\fR, alors il est possible pour un utilisateur d'importer le nom explicitement, mais pas implicitement. C'est\-a\*`\-dire qu'il pourrait dire .PP .Vb 1 \& use Module 'open'; .Ve .PP et cela importerait la surcharge \f(CW\*(C`open\*(C'\fR. Mais s'il disait .PP .Vb 1 \& use Module; .Ve .PP il obtiendrait les importations par de\*'faut sans les surcharges. .PP Le me\*'canisme pre\*'ce\*'dent de surcharge des e\*'le\*'ments pre\*'de\*'finis est restreint, assez de\*'libe\*'re\*'ment, au paquetage qui re\*'clame l'importation. Il existe une seconde me\*'thode parfois applicable lorsque vous de\*'sirez surcharger partout une fonction pre\*'de\*'finie, sans tenir compte des frontie\*`res entre espaces de noms. Cela s'obtient en important un sous-programme dans l'espace de noms spe\*'cial \f(CW\*(C`CORE::GLOBAL::\*(C'\fR. Voici un exemple qui remplace assez effronte\*'ment l'ope\*'rateur \f(CW\*(C`glob\*(C'\fR par quelque chose qui comprend les expressions rationnelles. .PP .Vb 4 \& package REGlob; \& require Exporter; \& @ISA = 'Exporter'; \& @EXPORT_OK = 'glob'; \& \& sub import { \& my $pkg = shift; \& return unless @_; \& my $sym = shift; \& my $where = ($sym =~ s/^GLOBAL_// ? 'CORE::GLOBAL' : caller(0)); \& $pkg\->export($where, $sym, @_); \& } \& \& sub glob { \& my $pat = shift; \& my @got; \& local *D; \& if (opendir D, '.') { \& @got = grep /$pat/, readdir D; \& closedir D; \& } \& return @got; \& } \& 1; .Ve .PP Et voici comment on pourrait en (ab)user\ : .PP .Vb 6 \& #use REGlob 'GLOBAL_glob'; # surcharge glob() dans TOUS les \& # espaces de noms \& package Foo; \& use REGlob 'glob'; # surcharge glob() dans Foo:: \& # seulement \& print for <^[a\-z_]+\e.pm\e$>; # montre tous les modules pragmatiques .Ve .PP Le commentaire initial montre un exemple artificiel, voire me\*^me dangereux. En surchargeant \f(CW\*(C`glob\*(C'\fR globalement, vous forceriez le nouveau (et subversif) comportement de l'ope\*'rateur \f(CW\*(C`glob\*(C'\fR pour \&\fItous\fR les espaces de noms, sans la comple\*`te coope\*'ration des modules qui posse\*`dent ces espaces de noms, et sans qu'ils en aient me\*^me connaissance. Naturellement, ceci doit e\*^tre fait avec d'extre\*^mes pre\*'cautions \*(-- si jamais cela doit e\*^tre fait. .PP L'exemple \f(CW\*(C`REGlob\*(C'\fR ci-dessus n'imple\*'mente pas tous le support ne\*'cessaires pour surcharger proprement l'ope\*'rateur \f(CW\*(C`glob\*(C'\fR de perl. La fonction inte\*'gre\*'e \f(CW\*(C`glob\*(C'\fR a des comportements diffe\*'rents selon qu'elle apparai\*^t dans un contexte scalaire ou un contexte de lites, mais ce n'est pas le cas de notre \f(CW\*(C`REGlob\*(C'\fR. En fait, beaucoup de fonctions pre\*'de\*'finies de perl ont de tels comportements sensibles au contexte, et ceux-ci doivent e\*^tre supporte\*'s de fac\*,on ade\*'quate par une surcharge correctement e\*'crite. Pour un exemple pleinement fonctionnel de surcharge de \f(CW\*(C`glob\*(C'\fR, e\*'tudiez l'imple\*'mentation de \f(CW\*(C`File::DosGlob\*(C'\fR dans la bibliothe\*`que standard. .PP Lorsque vous surchargez une fonction pre\*'de\*'finie, votre surcharge devrait e\*^tre cohe\*'rente (si possible) avec la syntaxe native de l'originale. Vous pouvez le faire en utilisant le prototype approprie\*'. Pour obtenir le prototype d'une fonction pre\*'de\*'finie surchargeable, utilisez la fonction \f(CW\*(C`prototype\*(C'\fR avec comme argument \&\f(CW"CORE::nom_de_la_fonction"\fR (voir \*(L"prototype\*(R" in perlfunc). .PP Remarquez que certaines fonctions pre\*'de\*'finies utilise une syntaxe non repre\*'sentable par un prototype (par exemple \f(CW\*(C`system\*(C'\fR ou \f(CW\*(C`chomp\*(C'\fR). Si vous les surchargez, vous ne pourrez pas simuler leur syntaxe d'origine. .PP Les \*(L"fonctions\*(R" pre\*'de\*'finies \f(CW\*(C`do\*(C'\fR, \f(CW\*(C`require\*(C'\fR et \f(CW\*(C`glob\*(C'\fR peuvent elles-aussi e\*^tre surcharge\*'es, mais comme elles sont magiques, elles conservent leur syntaxe d'origine et vous n'avez pas besoin de de\*'finir de prototype pour leurs fonctions de remplacement. (Par contre, vous ne pouvez pas surcharger la syntaxe \f(CW\*(C`do BLOC\*(C'\fR). .PP \&\f(CW\*(C`require\*(C'\fR posse\*`de en plus un peu de magie noire ; si vous appelez votre fonction \f(CW\*(C`require\*(C'\fR de remplacement par \f(CW\*(C`require Foo::Bar\*(C'\fR, vous recevrez en fait l'argument \f(CW"Foo/Bar.pm"\fR dans \f(CW@_\fR. Voir \&\*(L"require\*(R" in perlfunc. .PP Et, en se re\*'fe\*'rant a\*` l'exemple pre\*'ce\*'dent, si vous surchargez \f(CW\*(C`glob\*(C'\fR, l'ope\*'rateur \*(L"glob\*(R" \f(CW\*(C`<<*>\*(C'\fR sera aussi surcharge\*'. .PP De manie\*`res similaire, la surcharge de la fonction \f(CW\*(C`readline\*(C'\fR surcharge aussi l'ope\*'rateur d'E/S e\*'quivalent \f(CW\*(C`\*(C'\fR. .PP Et pour finir, certaines fonctions pre\*'de\*'finies (comme \f(CW\*(C`exists\*(C'\fR ou \&\f(CW\*(C`grep\*(C'\fR) ne peuvent pas e\*^tre surcharge\*'es. .Sh "Autochargement" .IX Xref "autochargement AUTOLOAD" .IX Subsection "Autochargement" Si vous appelez un sous-programme qui n'est pas de\*'fini, vous obtenez ordinairement une erreur fatale imme\*'diate se plaignant que le sous-programme n'existe pas (De me\*^me pour les sous-programmes utilise\*'s comme me\*'thodes, lorsque la me\*'thode n'existe dans aucune classe de base du paquetage de la classe). Toutefois, si un sous-programme \&\f(CW\*(C`AUTOLOAD\*(C'\fR est de\*'fini dans le paquetage ou dans les paquetages utilise\*'s pour localiser le sous-programme originel, alors ce sous-programme \f(CW\*(C`AUTOLOAD\*(C'\fR est appele\*' avec les arguments qui auraient e\*'te\*' passe\*'s au sous-programme originel. Le nom pleinement qualifie\*' du sous-programme originel apparai\*^t magiquement dans la variable globale \&\f(CW$AUTOLOAD\fR du me\*^me paquetage que la routine \f(CW\*(C`AUTOLOAD\*(C'\fR. Le nom n'est pas passe\*' comme un argument ordinaire parce que, euh, eh bien, juste parce que, c'est pour c\*,a... .PP La plupart des routines \f(CW\*(C`AUTOLOAD\*(C'\fR chargent une de\*'finition du sous-programme requis en utilisant \fIeval()\fR, puis l'exe\*'cutent en utilisant une forme spe\*'ciale de \fIgoto()\fR qui efface la routine \&\f(CW\*(C`AUTOLOAD\*(C'\fR de la pile sans laisser de traces (Voir le module standard \&\f(CW\*(C`AutoLoader\*(C'\fR pour un exemple). Mais une routine \f(CW\*(C`AUTOLOAD\*(C'\fR peut aussi juste e\*'muler la routine et ne jamais la de\*'finir. Par exemple, supposons qu'une fonction non encore de\*'finie doive juste appeler \&\f(CW\*(C`system\*(C'\fR avec ces arguments. Tout ce que vous feriez est ceci\ : .PP .Vb 8 \& sub AUTOLOAD { \& my $program = $AUTOLOAD; \& $program =~ s/.*:://; \& system($program, @_); \& } \& date(); \& who('am', 'i'); \& ls('\-l'); .Ve .PP En fait, si vous pre\*'de\*'clarez les fonctions que vous de\*'sirez appeler de cette fac\*,on, vous n'avez me\*^mes pas besoin des parenthe\*`ses\ : .PP .Vb 4 \& use subs qw(date who ls); \& date; \& who "am", "i"; \& ls \-l; .Ve .PP Un exemple plus complet de ceci est le module Shell standard, qui peut traiter des appels inde\*'finis a\*` des sous-programmes comme des appels de programmes externes. .PP Des me\*'canismes sont disponibles pour aider les auteurs de modules a\*` de\*'couper les modules en fichiers autochargeables. Voir le module standard AutoLoader de\*'crit dans AutoLoader et dans AutoSplit, les modules standards SelfLoader dans SelfLoader, et le document expliquant comment ajouter des fonctions C au code Perl dans perlxs. .Sh "Attributs de sous-programme" .IX Xref "attribut sous-programme, attribut attribut de sous-programme attrs" .IX Subsection "Attributs de sous-programme" Une de\*'claration ou une de\*'finition de sous-programme peut contenir une liste d'attributs qui lui sont associe\*'s. Si une telle liste est pre\*'sente, elle est de\*'coupe\*'e aux espaces et aux deux-points et traite\*'e comme si un \f(CW\*(C`use attributes\*(C'\fR avait e\*'te\*' rencontre\*'. Voir attributes pour plus de de\*'tails sur les diffe\*'rents attributs actuellement supporte\*'s. Contrairement aux limitations de l'\f(CW\*(C`use attrs\*(C'\fR obsole\*`te, la syntaxe \f(CW\*(C`sub : ATTRLIST\*(C'\fR fonctionne pour associer les attributs a\*` une pre\*'de\*'claration, et pas seulement dans la de\*'finition de sous\-programme. .PP Les attributs doivent e\*^tre des identifiants simples valides (sans aucune ponctuation a\*` part le caracte\*`re \*(L"_\*(R"). Ils peuvent e\*^tre suivis d'une liste de parame\*`tres, qui n'est contro\*^le\*'e que pour voir si ses parenthe\*`ses ('(',')') sont correctement imbrique\*'es. .PP Exemples de syntaxe valide (me\*^me si les attributs sont inconnus)\ : .PP .Vb 3 \& sub fnord (&\e%) : switch(10,foo(7,3)) : expensive ; \& sub plugh () : Ugly('\e(") :Bad ; \& sub xyzzy : _5x5 { ... } .Ve .PP Exemples de syntaxe invalide\ : .PP .Vb 5 \& sub fnord : switch(10,foo() ; # () non e\*'quilibre\*'es \& sub snoid : Ugly('(') ; # () non e\*'quilibre\*'es \& sub xyzzy : 5x5 ; # "5x5" n'est pas un identifiant valide \& sub plugh : Y2::north ; # "Y2::north" n'est pas un identifiant simple \& sub snurt : foo + bar ; # "+" n'est pas un deux\-points ni une espace .Ve .PP La liste d'attributs est passe\*'e comme une liste de chai\*^nes constantes au code qui les associe au sous\-programme. En particulier, le second exemple de syntaxe valide ci-dessus a\*` cette allure en termes d'analyse syntaxique et d'invocation\ : .PP .Vb 1 \& use attributes _\|_PACKAGE_\|_, \e&plugh, q[Ugly('\e(")], 'Bad'; .Ve .PP Pour plus de de\*'tails sur les listes d'attributs et leur manipulation, voir attributes en Attributes::Handlers. .SH "VOIR AUSSI" .IX Header "VOIR AUSSI" Voir \*(L"Mode\*`les de fonctions\*(R" in perlref pour plus de de\*'tails sur les re\*'fe\*'rences et les fermetures. Voir perlxs pour apprendre a\*` appeler des sous-programmes en C depuis Perl. Voir perlembed pour apprendre a\*` appeler des sous-programmes Perl depuis C. Voir perlmod pour apprendre a\*` emballer vos fonctions dans des fichiers se\*'pare\*'s. Voir perlmodlib pour apprendre quels modules de bibliothe\*`ques sont fournis en standard sur votre syste\*`me. Voir perltoot pour apprendre a\*` faire des appels a\*` des me\*'thodes objet. .SH "TRADUCTION" .IX Header "TRADUCTION" .Sh "Version" .IX Subsection "Version" Cette traduction franc\*,aise correspond a\*` la version anglaise distribue\*'e avec perl 5.8.8. Pour en savoir plus concernant ces traductions, consultez . .Sh "Traducteur" .IX Subsection "Traducteur" Traduction\ : Roland Trique <\fIroland.trique@free.fr\fR>. Mise a\*` jour\ : Paul Gaborit . .Sh "Relecture" .IX Subsection "Relecture" Personne pour l'instant.