=encoding iso-8859-1 =head1 NOM perlsyn - syntaxe de Perl =head1 DESCRIPTION Un script Perl est constitué d'une suite de déclarations et d'instructions. Les seules choses qui doivent être déclarées en Perl sont les formats de rapports et les sous-programmes. Voir la sections ci-dessous pour plus d'informations sur ces déclarations. Tous les objets non initialisés créés par l'utilisateur sont présumés démarrer avec une valeur C ou C<0> jusqu'à ce qu'ils soient définis par une opération explicite telle qu'une affectation (vous pouvez toutefois obtenir des avertissement sur l'usage de valeurs non définies si vous le désirez). La séquence d'instructions est exécutée une seule fois, contrairement aux scripts B ou B, où la séquence est exécutée pour chaque ligne en entrée. Même si cela signifie que vous devez boucler explicitement sur les lignes de votre fichier (ou de vos fichiers) d'entrée, cela veut aussi dire que vous avez plus de contrôle sur les lignes ou les fichiers que vous traitez (En vérité, je mens - il est possible de faire une boucle implicite avec les options B<-n> ou B<-p>. C'est juste que ça n'est pas le comportement par défaut obligatoire comme en B ou en B). =head2 Déclarations Perl est, en majeure partie, un langage à syntaxe libre (La seule exception en est les déclarations de format, pour des raisons évidentes). Le texte situé entre un caractère C<"#"> et la fin de la ligne est un commentaire, et est ignoré. Si vous essayez d'utiliser C pour des commentaires dans le style du C, ce sera interprété soit comme une division, soit comme un pattern matching, en fonction du contexte, et les commentaires C du C++ auront juste l'air d'une expression régulière nulle, alors ne faites pas cela. Une déclaration peut être mise partout où une instruction peut trouver place, mais n'a pas d'effet sur l'exécution de la séquence d'instructions principale - les déclarations prennent toutes effet au moment de la compilation. Typiquement, toutes les déclarations sont placées au début ou à la fin du script. Toutefois, si vous utilisez des variables privées de portée lexicales créées avec C, vous devrez vous assurez que la définition de votre format ou de votre sous-programme est à l'intérieur du même bloc que le my si vous voulez pouvoir accéder à ces variables privées. La déclaration d'un sous-programme permet à un nom de sous-programme d'être utilisé comme s'il était un opérateur de liste à partir de ce point dans le programme. Vous pouvez déclarer un sous-programme sans le définir en disant C, ainsi : sub myname; $me = myname $0 or die "can't get myname"; Notez qu'il fonctionne comme un opérateur de liste, pas comme un opérateur unaire ; faites donc attention d'utiliser C au lieu de C<||> dans ce cas. Toutefois, si vous déclariez le sous-programme avec C, alors C fonctionnerait comme un opérateur unaire, donc C aussi bien que C<||> feraient l'affaire. Les déclarations de sous-programmes peuvent aussi être chargées à l'aide de l'instruction C ou bien à la fois chargées et importées dans votre espace de noms via l'instruction C. Voir L pour plus de détails. Une séquence d'instructions peut contenir des déclarations de variables de portée lexicale, mais à part pour déclarer un nom de variable, la déclaration fonctionne comme une instruction ordinaire, et est élaborée à l'intérieur de la séquence d'instructions en tant que telle. Cela signifie qu'elle a à la fois un effet à la compilation et lors de l'exécution. =head2 Instructions Simples Le seul type d'instruction simple est une expression évaluée pour ses effets de bord. Chaque instruction simple doit être terminée par un point-virgule, à moins qu'elle ne soit la dernière instruction d'un bloc, auquel cas le point-virgule est optionnel (Nous vous encourageons tout de même à placer ce point-virgule si le bloc prend plus d'une ligne, car vous pourriez éventuellement ajouter une autre ligne). Notez qu'il existe des opérateurs comme C et C qui ont l'air d'instructions composées, mais qui ne le sont pas (ce sont juste les TERMES d'une expression), et ont donc besoin d'une terminaison explicite s'ils sont utilisés comme dernier élément d'une instruction. Toute instruction simple peut être suivie de façon optionelle par un I modificateur, juste avant le point-virgule de terminaison (ou la fin du bloc). Les modificateurs possibles sont : if EXPR unless EXPR while EXPR until EXPR foreach EXPR Les modificateurs C et C ont la sémantique attendue, en supposant que vous parlez anglais. Le modificateur C est un itérateur : il place successivement C<$_> à chaque valeur de EXPR et exécute l'instruction. Les modificateurs C et C ont la sémantique habituelle "C loop" (la condition est évaluée en premier), sauf lorsqu'ils sont appliqués à un C-BLOC (ou à l'instruction désormais désapprouvée C-SOUS_PROGRAMME), auquel cas le bloc s'exécute une fois avant que la condition ne soit évaluée. C'est ainsi pour que vous puissiez écrire des boucles telles que : do { $line = ; ... } until $line eq ".\n"; Voir L. Notez aussi que l'instruction de contrôle de boucle décrite plus tard I fonctionnera I dans cette construction, car les modificateurs n'utilisent pas de labels de boucle. Désolé. Vous pouvez toujours mettre un autre bloc à l'intérieur (for C) ou autour (for C) pour réaliser ce genre de choses. Pour C, il suffit de doubler les accolades : do {{ next if $x == $y; # do something here }} until $x++ > $z; Pour C, vous devez faire quelque chose de plus élaboré : LOOP: { do { last if $x = $y**2; # do something here } while $x++ <= $z; } =head2 Instructions Composées En Perl, une séquence d'instructions qui définit une portée est appelée un bloc. Un bloc est parfois délimité par le fichier qui le contient (dans le cas d'un fichier requis, ou dans celui du programme en entier), et parfois un bloc est délimité par la longueur d'une chaîne (dans le cas d'un eval). Mais généralement, un bloc est délimité par des accolades. Nous appellerons cette construction syntaxique un BLOC. Les instructions composées suivantes peuvent être utilisées pour contrôler un flux : if (EXPR) BLOC if (EXPR) BLOC else BLOC if (EXPR) BLOC elsif (EXPR) BLOC ... else BLOC LABEL while (EXPR) BLOC LABEL while (EXPR) BLOC continue BLOC LABEL for (EXPR; EXPR; EXPR) BLOC LABEL foreach VAR (LIST) BLOC LABEL BLOC continue BLOC Notez que, contrairement au C et au Pascal, tout ceci est défini en termes de BLOCs, et non d'instructions. Ceci veut dire que les accolades sont I - aucune instruction ne doit traîner. Si vous désirez écrire des conditionnelles sans accolades, il existe plusieurs autres façons de le faire. Les exemples suivants font tous la même chose : if (!open(FOO)) { die "Can't open $FOO: $!"; } die "Can't open $FOO: $!" unless open(FOO); open(FOO) or die "Can't open $FOO: $!"; # FOO or bust! open(FOO) ? 'hi mom' : die "Can't open $FOO: $!"; # ce dernier est un peu exotique L'instruction C est directe. Puisque les BLOCs sont toujours entourés d'accolades, il n'y a jamais d'ambiguïté pour savoir à quel C correspond un C. Si vous utilisez C à la place de C, le sens du test est inversé. L'instruction C exécute le bloc tant que l'expression est vraie (son évaluation ne renvoie pas une chaîne nulle (C<"">) ou C<0> ou C<"0")>. Le LABEL est optionnel, et s'il est présent, il est constitué d'un identifiant suivi de deux points. Le LABEL identifie la boucle pour les instructions de contrôle de boucle C, C, et C. Si le LABEL est omis, l'instruction de contrôle de boucle se réfère à la boucle incluse dans toutes les autres. Ceci peut amener une recherche dynamique dans votre pile au moment de l'exécution pour trouver le LABEL. Un comportement aussi désespéré provoque un avertisement si vous utilisez l'option B<-w>. (Note au relecteur : Heu, j'ai bon ? NDT). S'il existe un BLOC C, il est toujours exécuté juste avant que la condition ne soit à nouveau évaluée, dde la même manière que la troisième partie d'une boucle C en C. Il peut ainsi être utilisé pour incrémenter une variable de boucle, même lorsque la boucle a été continuée via l'instruction C (qui est similaire à l'instruction C en C). =head2 Contrôle de Boucle La commande C a le même rôle que l'instruction C en C ; elle démarre la prochaine itération de la boucle : LINE: while () { next LINE if /^#/; # elimine les commentaires ... } La commande C est identique à l'instruction C en C (telle qu'elle est utilisée dans les boucles) ; elle sort immédiatement de la boucle en question. Le bloc C, s'il existe, n'est pas exécuté : LINE: while () { last LINE if /^$/; # sort quand on en a fini avec l'en-tete ... } La commande C redémarre le bloc de la boucle sans réévaluer la condition. Le bloc C, s'il existe, n'est I exécuté. Cette commande est normalement utilisée par les programmes qui veulent se mentir à eux-mêmes au sujet de ce qui vient de leur être fourni en entrée. Par exemple, lors du traitement d'un fichier comme F. Si vos lignes en entrée sont susceptibles de se terminer par un antislash pour indiquer leur continuation, vous pouvez vouloir poursuivre et récupérer l'enregistrement suivant. while (<>) { chomp; if (s/\\$//) { $_ .= <>; redo unless eof(); } # now process $_ } qui est le raccourci Perl pour la version plus explicite : LINE: while (defined($line = )) { chomp($line); if ($line =~ s/\\$//) { $line .= ; redo LINE unless eof(); # pas eof(ARGV)! } # now process $line } Notez que s'il y avait un bloc C dans le code ci-dessus, il serait exécuté même pour les lignes rejetées. Ceci est souvent utilisé pour réinitialiser les compteurs de lignes ou les recherches de motifs C. # inspire par :1,$g/fred/s//WILMA/ while (<>) { ?(fred)? && s//WILMA $1 WILMA/; ?(barney)? && s//BETTY $1 BETTY/; ?(homer)? && s//MARGE $1 MARGE/; } continue { print "$ARGV $.: $_"; close ARGV if eof(); # reinitialise $. reset if eof(); # reinitialise ?pat? } Si le mot C est remplacé par le mot C, le sens du test est inversé, mais la condition est toujours testée avant la première itération. Les instructions de contrôle de boucle ne fonctionnent pas dans un C ou dans un C, puisque ce ne sont pas des boucles. Vous pouvez toutefois doubler les accolades pour qu'elles le deviennent. if (/pattern/) {{ next if /fred/; next if /barney/; # mettre quelque chose ici }} La forme C, disponible en Perl 4, ne l'est plus. Remplacez toutes les occurrences de C par C. =head2 Boucles For Les boucles C de Perl dans le style de C fonctionnent exactement de la même façon que les boucles C correspondantes ; cela signifie que ceci : for ($i = 1; $i < 10; $i++) { ... } est la même chose que ça : $i = 1; while ($i < 10) { ... } continue { $i++; } (Il existe une différence mineure : la première forme implique une portée lexicale pour les variables déclarées avec C dans l'expression d'initialisation). En plus du bouclage classique dans les indices d'un tableau, C peut se prêter à de nombreuses autres applications intéressantes. En voici une qui évite le problème que vous rencontrez si vous testez explicitement la fin d'un fichier sur un descripteur de fichier interactif, ce qui donne l'impression que votre programme se gèle. $on_a_tty = -t STDIN && -t STDOUT; sub prompt { print "yes? " if $on_a_tty } for ( prompt(); ; prompt() ) { # faire quelque chose ici } =head2 Boucles Foreach La boucle C itère sur une liste de valeurs normale et fixe la variable VAR à chacune de ces valeurs successivement. Si la variable est précédée du mot-clé C, alors elle a une portée limitée du point de vue lexical, et n'est par conséquent visible qu'à l'intérieur de la boucle. Autrement, la variable est implicitement locale à la boucle et reprend sa valeur précédente à la sortie de la boucle. Si la variable était précédemment déclaré par C, elle utilise cette variable au lieu de celle qui est globale, mais elle est toujours locale à la boucle (Notez qu'une variable de portée lexicale limitée peut poser des problèmes si vous avez des déclarations de sous-programmes ou de formats à l'intérieur de la boucle qui s'y réfère). Le mot-clé C est en fait un synonyme du mot-clé C, vous pouvez donc utiliser C pour sa lisibilité ou C pour sa concision (Ou parce que le Bourne shell vous est plus familier que I, vous rendant l'utilisation de C plus naturelle). Si VAR est omis, C<$_> est fixée à chaque valeur. Si un élément de LIST est une lvalue, vous pouvez la modifier en modifiant VAR à l'intérieur de la boucle. C'est parce que la variable d'index de la boucle C est un alias implicite de chaque élément de la liste sur laquelle vous bouclez. Si une partie de LIST est un tableau, C sera très troublé dans le cas où vous lui ajouteriez ou retireriez des éléments à l'intérieur de la boucle, par exemple à l'aide de C. Ne faites donc pas cela. C ne fera probablement pas ce que vous désirez si VAR est une variable liée ou une autre variable spéciale. Ne faites pas cela non plus. Exemples : for (@ary) { s/foo/bar/ } foreach my $elem (@elements) { $elem *= 2; } for $count (10,9,8,7,6,5,4,3,2,1,'BOOM') { print $count, "\n"; sleep(1); } for (1..15) { print "Merry Christmas\n"; } foreach $item (split(/:[\\\n:]*/, $ENV{TERMCAP})) { print "Item: $item\n"; } Voici comment un programmeur C pourrait coder un algorithme en Perl : for (my $i = 0; $i < @ary1; $i++) { for (my $j = 0; $j < @ary2; $j++) { if ($ary1[$i] > $ary2[$j]) { last; # ne peut pas sortir totalement :-( } $ary1[$i] += $ary2[$j]; } # voici l'endroit ou ce last m'emmene } Tandis que voici comment un programmeur Perl plus à l'aise avec l'idiome pourrait le faire : OUTER: foreach my $wid (@ary1) { INNER: foreach my $jet (@ary2) { next OUTER if $wid > $jet; $wid += $jet; } } Vous voyez à quel point c'est plus facile ? C'est plus propre, plus sûr, et plus rapide. C'est plus propre parce qu'il y a moins de bruit. C'est plus sûr car si du code est ajouté entre les deux boucles par la suite, le nouveau code ne sera pas exécuté accidentellement. Le C itère de façon explicite sur l'autre boucle plutôt que de simplement terminer celle qui est à l'intérieur. Et c'est plus rapide parce que Perl exécute une instruction C plus rapidement qu'une boucle C équivalente. =head2 BLOCs de Base et Instruction Switch Un BLOC en lui-même (avec ou sans label) est d'un point de vue sémantique, équivalent à une boucle qui s'exécute une fois. Vous pouvez donc y utilisez n'importe quelle instruction de contrôle de boucle pour en sortir ou le recommencer (Notez que ce n'est I vrai pour les blocs C, C, ou C contrairement à la croyance populaire, qui I comptent I pour des boucles). Le bloc C est optionnel. La construction de BLOC est particulièrement élégante pour créer des structures case. SWITCH: { if (/^abc/) { $abc = 1; last SWITCH; } if (/^def/) { $def = 1; last SWITCH; } if (/^xyz/) { $xyz = 1; last SWITCH; } $nothing = 1; } Il n'y a pas d'instruction C officielle en Perl, car il existe déjà plusieurs façons d'écrire l'équivalent. Vous pourriez écrire à la place de ce qui précède : SWITCH: { $abc = 1, last SWITCH if /^abc/; $def = 1, last SWITCH if /^def/; $xyz = 1, last SWITCH if /^xyz/; $nothing = 1; } (Ce n'est pas aussi étrange que cela en a l'air une fois que vous avez réalisé que vous pouvez utiliser des "opérateurs" de contrôle de boucle à l'intérieur d'une expression, c'est juste l'opérateur virgule, normal en C). ou SWITCH: { /^abc/ && do { $abc = 1; last SWITCH; }; /^def/ && do { $def = 1; last SWITCH; }; /^xyz/ && do { $xyz = 1; last SWITCH; }; $nothing = 1; } ou formaté de façon à avoir un peu plus l'air d'une instruction C "convenable" : SWITCH: { /^abc/ && do { $abc = 1; last SWITCH; }; /^def/ && do { $def = 1; last SWITCH; }; /^xyz/ && do { $xyz = 1; last SWITCH; }; $nothing = 1; } ou SWITCH: { /^abc/ and $abc = 1, last SWITCH; /^def/ and $def = 1, last SWITCH; /^xyz/ and $xyz = 1, last SWITCH; $nothing = 1; } or même, horreur, if (/^abc/) { $abc = 1 } elsif (/^def/) { $def = 1 } elsif (/^xyz/) { $xyz = 1 } else { $nothing = 1 } Un idiome courant pour une instruction C est d'utiliser l'aliasing de C pour effectuer une affectation temporaire de C<$_> pour une reconnaissance pratique des cas : SWITCH: for ($where) { /In Card Names/ && do { push @flags, '-e'; last; }; /Anywhere/ && do { push @flags, '-h'; last; }; /In Rulings/ && do { last; }; die "unknown value for form variable where: `$where'"; } Une autre approche intéressante de l'instruction switch est de s'arranger pour qu'un bloc C renvoie la valeur correcte : $amode = do { if ($flag & O_RDONLY) { "r" } # XXX : n'est-ce pas 0? elsif ($flag & O_WRONLY) { ($flag & O_APPEND) ? "a" : "w" } elsif ($flag & O_RDWR) { if ($flag & O_CREAT) { "w+" } else { ($flag & O_APPEND) ? "a+" : "r+" } } }; ou print do { ($flags & O_WRONLY) ? "write-only" : ($flags & O_RDWR) ? "read-write" : "read-only"; }; Ou si vous êtes certain que toutes les clauses C<&&> sont vraies, vous pouvez utiliser quelque chose comme ceci, qui "switche" sur la valeur de la variable d'environnement C. #!/usr/bin/perl # choisir une page du jargon file selon le browser $dir = 'http://www.wins.uva.nl/~mes/jargon'; for ($ENV{HTTP_USER_AGENT}) { $page = /Mac/ && 'm/Macintrash.html' || /Win(dows )?NT/ && 'e/evilandrude.html' || /Win|MSIE|WebTV/ && 'm/MicroslothWindows.html' || /Linux/ && 'l/Linux.html' || /HP-UX/ && 'h/HP-SUX.html' || /SunOS/ && 's/ScumOS.html' || 'a/AppendixB.html'; } print "Location: $dir/$page\015\012\015\012"; Ce type d'instruction switch ne fonctionne que lorsque vous savez que les clauses C<&&> seront vraies. Si vous ne le savez pas, l'exemple précédent utilisant C devrait être utilisé. Vous pourriez aussi envisager d'écrire un hachage au lieu de synthétiser une instruction C. =head2 Goto Bien que cela ne soit pas destiné aux âmes sensibles, Perl supporte une instruction C. Un LABEL de boucle n'est pas en vérité une cible valide pour un C ; c'est juste le nom de la boucle. Il existe trois formes : C-LABEL, C-EXPR, et C-&NAME. La forme C-LABEL trouve l'instruction marquée par LABEL et reprend l'exécution à cet endroit. Elle ne peut pas être utilisée pour aller dans une structure qui nécessite une initialisation, comme un sous-programme ou une boucle C. Elle ne peut pas non plus être utilisée pour aller dans une structure très optimisée. Elle peut être employée pour aller presque n'importe où ailleurs à l'intérieur de la portée dynamique, y compris hors des sous-programmes, mais il est habituellement préférable d'utiliser une autre construction comme C ou C. L'auteur de Perl n'a jamais ressenti le besoin d'utiliser cette forme de C (en Perl, à vrai dire - C est une toute autre question). La forme C-EXPR attend un nom de label, dont la portée sera résolue dynamiquement. Ceci permet des Cs calculés à la mode de FORTRAN, mais ce n'est pas nécessairement recommandé si vous optimisez la maintenance du code : goto ("FOO", "BAR", "GLARCH")[$i]; La forme C-&NAME est hautement magique, et substitue au sous-programme en cours d'exécution un appel au sous-programme nommé. C'est utilisé par les sous-programmes C qui veulent charger une autre routine et prétendre que cette autre routine a été appelée à leur place (sauf que toute modification de C<@_> dans le sous-programme en cours est propagée à l'autre routine). Après le C, même C ne pourra pas dire que cette routine n'a pas été appelée en premier. Dans presque tous les cas similaires, une bien bien meilleure idée est d'utiliser les mécanismes de contrôle de flux structurés comme C, C, ou C au lieu de s'en remettre à un C. Pour certaines applications, la paire C - die() pour le traitement des exceptions peut aussi être une approche prudente. =head2 POD : Documentation Enfouie Perl dispose d'un mécanisme pour mélanger de la documentation avec le code source. Lorsqu'il s'attend au début d'une nouvelle instruction, si le compilateur rencontre une ligne commençant par un signe égal et un mot, comme ceci =head1 Here There Be Pods! Alors ce texte et tout ce qui suit jusqu'à et y compris une ligne commençant par C<=cut> sera ignoré. Le format du texte en faisant partie est décrit dans L. Ceci vous permet de mélanger librement votre code source et votre documentation, comme dans =item snazzle($) La fonction snazzle() se comportera de la facon la plus spectaculaire que vous pouvez imaginer, y compris la pyrotechnie cybernetique. =cut retour au compilateur, nuff of this pod stuff! sub snazzle($) { my $thingie = shift; ......... } Notez que les traducteurs pod ne devraient traiter que les paragraphes débutant par une directive pod (cela rend leur analyse plus simple), tandis que le compilateur sait en réalité chercher des séquences pod même au milieu d'un paragraphe. Cela veut que le matériel secret qui suit sera ignoré à la fois par le compilateur et les traducteurs. $a=3; =truc secret warn "Neither POD nor CODE!?" =cut back print "got $a\n"; Vous ne devriez probablement pas vous reposer sur le fait que le C sera ignoré pour toujours. Les traducteurs pod ne sont pas tous bien élevés de ce point de vue, et le compilateur deviendra peut-être plus regardant. On peut aussi utiliser des directives pod pour mettre rapidement une partie de code en commentaire. =head2 Bons Vieux Commentaires (Non !) À la manière du préprocesseur C, Perl peut traiter des directives de ligne. Avec cela, on peut contrôler l'idée que Perl se fait des noms de fichiers et des numéros de ligne dans les messages d'erreur ou dans les avertissements (en particulier pour les chaînes traitées par C). La syntaxe de ce mécanisme est la même que pour pour la plupart des préprocesseurs C : elle reconnaît l'expression régulière C où C<$1> est le numéro de la prochaine ligne, et C<$2> le nom de fichier optionnel (spécifié entre apostrophes). Voici quelques exemples que vous devriez pouvoir taper dans votre interpréteur de commandes : % perl # line 200 "bzzzt" # the `#' on the previous line must be the first char on line die 'foo'; __END__ foo at bzzzt line 201. % perl # line 200 "bzzzt" eval qq[\n#line 2001 ""\ndie 'foo']; print $@; __END__ foo at - line 2001. % perl eval qq[\n#line 200 "foo bar"\ndie 'foo']; print $@; __END__ foo at foo bar line 200. % perl # line 345 "goop" eval "\n#line " . __LINE__ . ' "' . __FILE__ ."\"\ndie 'foo'"; print $@; __END__ foo at goop line 345. =head1 TRADUCTION =head2 Version Cette traduction française correspond à la version anglaise distribuée avec perl 5.005_02. Pour en savoir plus concernant ces traductions, consultez L. =head2 Traducteur Roland Trique