Dernière version sur https://formation-perl.fr/guide-perl.html
© 2002-2024 Sylvain Lhullier - Permission est accordée de copier et distribuer ce document sans modification
et à condition de fournir un lien vers la page https://formation-perl.fr/guide-perl.html
Envie d'une formation Perl ?
Sylvain Lhullier propose des formations au langage Perl,
contactez-le.
Ici nous allons apprendre à contrôler le flux des instructions en Perl. En effet un programme n'est pas qu'une simple suite d'instructions se déroulant linéairement une fois et une seule.
Il faut savoir que Perl (tout comme le C) permet d'indenter notre code comme bon nous semble, les exemples qui suivent comportent donc des choix personnels d'indentation qui peuvent diverger des vôtres.
Ces instructions permettent de conditionner l'exécution d'instructions
à la valeur de vérité d'une expression.
L'instruction la plus usitée est le if
(si en français)
qui a besoin d'une expression et d'un bloc d'instructions.
Cette expression sera évaluée en contexte scalaire
et servira de condition ; si elle est vérifiée, le bloc d'instructions
sera exécuté.
if( $x != 1 ) { print "$x\n"; }
Ce code Perl a pour effet d'afficher la variable $x
si elle ne vaut pas 1. Plusieurs instructions peuvent être placées dans
le bloc, elles seront alors toutes exécutées si la condition est vraie.
Notez que les accolades ({}
) sont
obligatoires pour délimiter le bloc (contrairement au C).
Il est possible d'exécuter d'autres instructions dans le cas où la
condition est fausse. On utilise pour cela l'opérateur else
(sinon en français)
qui, lui aussi, est suivi d'un bloc d'instructions :
if( $x == $y ) { print "\$x et \$y sont égaux\n"; } else { print "\$x et \$y sont différents\n"; }
Le fait que les accolades sont obligatoires a pour conséquence que le programme suivant est incorrect :
if( condition1 ) { instructions1 } else # Attention ce code est incorrect if( condition2 ) { instructions2 }
Il faut en effet entourer le second if
par
des accolades comme ceci :
if( condition1 ) { instructions1 } else { if( condition2 ) { instructions2 } }
Si le programmeur se sent des envies de devenir sylviculteur
en plantant des forêts d'ifs, il faudrait donc qu'il utilise
de multiples couples d'accolades. Pour ne pas rencontrer les mêmes
problèmes que le Lisp en rencontre pour les parenthèses ;-)
,
Perl met à notre disposition l'instruction
elsif
qui permet de cumuler le comportement
d'un else
et d'un if
tout en faisant l'économie d'un couple d'accolades :
if( condition1 ) { instructions1 } elsif( condition2 ) { instructions2 } else { instructions3 }
L'instruction switch
de C n'a pas
d'équivalent direct en Perl ; il faut pour cela planter
une forêt d'ifs, comme dans l'exemple précédent.
Mais Perl n'en reste pas là. Il existe une syntaxe très utilisée pour effectuer une unique instruction si une condition est vérifiée :
instruction if( condition );
On parle ici de modificateur d'instruction.
Pour cette syntaxe, les parenthèses sont optionnelles autour de la
condition, mais je vous conseille de les mettre systématiquement pour
une meilleure lisibilité.
Le code suivant affiche la variable $s
si elle est définie :
print "$s\n" if( defined($s) );
On notera que cette syntaxe ne permet pas l'usage d'un
else
.
L'instruction unless
a exactement
le même rôle que le if
, à la différence
que les instructions seront effectuées si la condition
est fausse (il est aussi moins dépaysant d'en faire des forêts).
unless( expression )
est équivalent à
if( !(expression) )
dans toutes les constructions
précédemment citées.
Les boucles permettent d'exécuter plusieurs fois les mêmes instructions
sans avoir à écrire plusieurs fois les mêmes lignes de code.
Bien souvent nous avons besoin de modifier une variable à chaque étape ;
dans ce cas nous utiliserons l'instruction for
(pour en français) dont voici la syntaxe :
for( initialisation; condition; incrément ) { instructions; }
La boucle for
prend trois expressions entre
parenthèses : la première expression permet d'initialiser la
variable de boucle, la deuxième est une condition de continuation
et la dernière permet de modifier la valeur de la variable de boucle.
Quand la boucle démarre, la variable est initialisée (expression 1) et le test est effectué (expression 2). Si cette condition est vérifiée, le bloc d'instructions est exécuté. Quand le bloc se termine, la variable est modifiée (expression 3) et le test est de nouveau effectué (expression 2). Si la condition est vérifiée, le bloc d'instructions est réexécuté avec la nouvelle valeur pour la variable de boucle.
Tant que le test reste vrai, le bloc d'instructions et l'expression de modification de la variable sont exécutés. À l'arrêt de la boucle, les instructions qui suivent la boucle sont exécutées.
L'exemple suivant affiche tous les entiers pairs de 0 à 20 inclus :
for( my $i=0; $i<=20; $i+=2 ) { print "$i\n"; }
La boucle s'arrête lorsque $i
vaut 22.
Cette variable est déclarée dans le bloc d'initialisation
et n'existe donc que dans la boucle. Notez qu'il est tout à
fait possible d'utiliser une variable pré-existante comme
variable de boucle (et donc de ne pas faire de my
dans la partie initialisation) ; dans ce cas, après exécution
de la boucle, la variable vaut la dernière valeur qui lui a été
affectée au cours de la boucle.
Une autre boucle existe : la boucle while
(tant que en français)
dont voici la syntaxe :
while( condition ) { instructions; }
Les instructions sont effectuées tant que la condition est vraie. La partie initialisation doit avoir été effectuée avant la boucle ; la partie modification de la variable doit avoir lieu dans le bloc d'instructions.
L'exemple suivant affiche lui aussi les entiers pairs de 0 à 20 :
my $i = 0; while( $i <= 20 ) { print "$i\n"; $i+=2; }
La seule différence entre les deux exemples est le fait que,
dans le cas du while
, la variable
$i
existe après la boucle.
Comme pour le if
, certaines facilités sont
offertes pour le while
. Tout d'abord,
la syntaxe suivante est correcte :
instruction while( condition );
Elle permet d'exécuter plusieurs fois une instruction et une seule tant qu'une condition est vérifiée.
Ensuite, il existe une instruction until
(jusqu'à en français) qui a la même syntaxe
que le while
,
mais qui demande une condition d'arrêt (comme unless
pour if
) : until(condition)
est équivalent à while(!(condition))
.
Lors de l'exécution d'une boucle, il est fréquent de rencontrer
des cas particuliers que l'on souhaiterait sauter ou pour lesquels
on aimerait mettre fin à la boucle. Les instructions next
,
last
et redo
vont nous servir à cela
dans les boucles for
, while
ou until
.
L'instruction next
(suivant en
français) provoque la fin de l'exécution du bloc, le programme évalue
directement l'incrément (dans le cas d'une boucle for
) puis le test
est effectué.
L'instruction last
(dernier en
français) provoque la fin de la boucle, ni l'incrément ni le test
ne sont effectués.
L'instruction redo
(refaire en
français) provoque le redémarrage du bloc d'instructions sans que la
condition ni l'incrémentation ne soient effectuées.
L'exemple suivant est une autre façon d'imprimer à l'écran les entiers pairs de 0 à 20 :
my $i = -1; while( 1 ) { # 1 est vrai $i++; last if( $i > 20 ); next if( $i%2 != 0 ); print "$i\n"; }
Dans le cas où l'on souhaite exécuter le bloc d'instructions une fois avant d'effectuer le test, on peut utiliser la syntaxe suivante :
do { instruction; } while( condition );
Pour des raisons trop longues à exposer ici, il ne faut pas utiliser
les instructions next
, last
et redo
dans le cas de la boucle do while
.
Nous verrons dans la suite qu'il existe une autre structure
de boucle : foreach
. Elle permet d'itérer sur les
éléments d'une liste (notion que nous aborderons à cette occasion). Vous
verrez alors qu'en Perl on utilise beaucoup le foreach
et assez peu le for(;;)
.
Voici un petit exemple de programme Perl ; il n'est pas très utile dans la vie de tous les jours, mais il utilise beaucoup des notions abordées jusqu'ici. Si vous parvenez à comprendre tout ce qu'il fait, vous n'aurez pas perdu votre temps à le lire !
1: #!/usr/bin/perl 2: use strict; 3: use warnings; 4: my $v ="##########"; 5: for( my $i=9; $i>0; $i-- ) { 6: print("$i impair\n") 7: if( $i % 2 ); 8: print( "-"x$i . "\n") 9: unless( $i % 3 ); 10: substr( $v, $i, 0 ) = $i; 11: } 12: print("$v\n");
Voici le détail du rôle des lignes.
2: Cette instruction rend le langage moins permissif, je vous conseille de toujours la placer au début de vos programmes.
3: Cette instruction déclenche d'éventuels messages d'avertissement.
5: Une boucle for
. Déclaration et initialisation
à 9 de la variable de boucle $i
. Nous continuerons
tant qu'elle est strictement positive ; à chaque étape nous la
décrémenterons : elle variera donc de 9 à 1.
6 et 7 : Affichage d'une chaîne dans le cas où $i
est impair.
8 et 9 : Affichage d'une chaîne dans le cas où $i
est multiple de 3. Cette chaîne comporte $i
caractères
moins (-
).
10: Insertion de $i
dans la chaîne
$v
en position $i
(une longueur de 0 provoque une insertion et non un remplacement).
L'affichage suivant est donc effectué :
9 impair --------- 7 impair ------ 5 impair 3 impair --- 1 impair #1#2#3#4#5#6#7#8#9#
Avez-vous tout compris ?