SELFHTML/Quickbar
CGI/Perl
Éléments de langage Perl
![]() |
Boucles et commandes de saut |
![]() |
|
![]() |
À l'aide de boucles while vous pouvez répéter des instructions de programme aussi longtemps que la condition formulée dans la boucle est remplie. Avec les boucles until vous pouvez répéter des instructions de programme jusqu'à ce que la condition formulée dans la boucle soit remplie.
#!/usr/bin/perl $i = 1; print "d'abord la racine carrée de 1 à 10...\n\n"; while($i <= 10) { print "La racine carrée de ", $i, " est ", sqrt($i), "\n"; $i++; } $i = 1; print "et maintenant le carré des nombres de 1 à 10...\n\n"; until($i > 10) { print "Le carré de ", $i, " est ", $i * $i, "\n"; $i++; } |
#!/usr/bin/perl $fichieracces = "../../docs/access.log"; $acces = 0; $succes = 0; open(FICHIER, "<".$fichieracces) || "fichier non trouvé!\n"; { while(<FICHIER>) { if(/HTTP\/1.0" 200/) # rechercher d'après 'HTTP/1.0" 200' (= accès réussis) { $succes ++; } $acces ++; } } print "De ", $acces, $succes, " accès ont réussi\n"; |
Une boucle while (comme dans l'exemple 1 ci-dessus, première partie)
commence avec le mot while (while = aussi longtemps que),
suivi entre parenthèses accolades de la condition. Pour formuler une
condition, vous avez besoin en règle générale d' opérateurs
de comparaison. Le contenu de la boucle est répété aussi longtemps
que la condition de la boucle est vraie.
Une boucle until (comme dans l'exemple 1 ci-dessus, deuxième partie) commence avec le mot until (until = jusqu'a ce que). Il s'agit ici d'une autre formulation logique que pour while. Le contenu de la boucle est répété jusqu'à ce que la condition de la boucle soit vraie. À part ceci, les mêmes règles valent pour les boucles until que pour les boucles while. Veillez cependant à ce que la formulation de le condition de la boucle soit d'une logique absolue! Ainsi dans l'exemple, les conditions des boucles while($i <= 10) et until($i > 10) signifient-elles exactement la même chose.
L'exemple 2 ci-dessus montre un cas d'utilisation typique à Perl de la boucle
avec while. Dans l'exemple, un fichier est lu ligne par ligne. Il
s'agit d'un fichier log comme le crée un serveur WWW pour avoir la trace des
accès. Dans ce cas spécial, il n'est pas besoin d'opérateur de comparaison
pour la condition de la boucle. La boucle s'interrompt automatiquement quand
toutes les lignes du fichier sont lues (à propos de cette règle voir aussi lire
et écrire des fichiers ainsi que, pour la recherche de chaînes de
caractères, la partie
expressions
régulières).
Dans les boucles, notez toujours les instructions dans des parenthèses accolades { et }, même si ce n'est qu'une seule instruction.
Veillez, pour les boucles avec opérateurs de comparaison dans la condition de la boucle, qu'il y ait toujours au moins une possibilité pour mettre fin à la boucle après un temps raisonnable. Dans le cas contraire, vous créez une "boucle sans fin" qui peut mener à un "plantage" du système!
Pour éviter les boucles sans fin, vous avez besoin de quelque chose qui conduise
à un moment quelconque à une sortie de la boucle. Fréquemment sont
définis à cet effet des "compteurs" - dans l'exemple 1,
la variable scalaire simple $i.
Cette variable scalaire simple a dans l'exemple une valeur
initiale de 1, et est incrémentée à chaque passage dans la boucle de la valeur 1
par l'instruction $i++;, de telle sorte que la condition de la
boucle sera remplie à un moment quelconque.
Une autre possibilité de contrôler et d'interrompre des boucles est
proposée par les commandes
de saut.
![]() ![]() |
Avec cette sorte de boucle, ce n'est pas la condition de la boucle qui est d'abord évaluée pour, d'après le résultat, exécuter un bloc d'instructions dans la boucle, mais c'est d'abord le bloc d'instructions qui est exécuté, à la suite de quoi la condition de la boucle est évaluée. La boucle est donc dans tous les cas exécutée au moins une fois, peu importe l'énoncé de la condition. Cela peut être judicieux si dans la condition de la boucle vous travaillez avec des variables dont vous ne connaissez pas la valeur exacte au départ de la boucle.
#!/usr/bin/perl $Nom = "Serge"; do { print $Nom, "\n"; $Nom = "Virtuelle"; } while($Nom ne "Virtuelle") |
#!/usr/bin/perl $Nom= "Serge"; do { print $Nom, "\n"; $Nom= "Virtuelle"; } until($Nom eq "Virtuelle") |
Une boucle de ce type commence avec le mot clé do. Ensuite suit le
bloc d'instructions de la boucle, placé comme d'habitude entre
parenthèses accolades { et }. Après la parenthèse
accolade de fermeture suit la condition de la boucle. La condition de la boucle
peut être formulée avec while (aussi longtemps que) ou avec until (jusqu'à
ce que). Ici entrent en vigueur les mêmes règles que pour les boucles
avec while/until.
Veillez aussi pour les boucles do..while/until à ne pas créer de
boucles sans fin. Les deux exemples ci-dessus ont le même effet, à savoir la
sortie une seule fois du nom "Serge". Les deux exemples ne se
différencient que par la formulation de la condition de la boucle. Si dans ces
deux exemples vous inversiez les opérateurs
de comparaison eq et ne, une boucle sans fin en
résulterait dans les deux cas!
![]() ![]() |
Les boucles avec for ou foreach se différencient des boucles avec while ou until en ce qu'elles prévoient déjà dans la condition de la boucle une condition d'interruption fixe. Pour cette raison, de telles boucles sont avant tout adéquates dans les cas où les valeurs initiale et finale sont d'emblée fixées.
#!/usr/bin/perl for($i=0;$i<=255;$i++) { printf("%4d = %2X",$i, $i); if($i % 8 == 0) { print "\n"; } } |
#!/usr/bin/perl @Alphabet = (A..Z); for(@Alphabet) { print $_, " est la ", $i+1, "ème lettre de l'alphabet \n"; $i++; } |
#!/usr/bin/perl foreach $i (1..100) { next if $i % 2 == 0; print $i, "\n" if $i % 3 == 0; } |
Une boucle for commence par le mot for, suivi entre
parenthèses accolades de la formulation de la condition de la boucle. Pour les
boucles for classiques, conformes à C, trois instructions sont notées dans la
condition de la boucle. Dans la première instruction est défini et initialisé
un compteur. Dans l'exemple 1, un compteur $i est défini et
initialisé avec la valeur 0. La deuxième instruction contient la condition à
partir de laquelle la boucle sera interrompue. Pour cela, vous avez besoin d' opérateurs
de comparaison. Dans la troisième instruction, le compteur de boucle
est modifié de telle façon qu'il finira par remplir la condition notée dans
la deuxième instruction. Dans l'exemple, $i est incrémenté de 1 à
chaque passage de boucle, de sorte que sa valeur dépassera 255 à un moment ou
à un autre et remplira ainsi la condition de la deuxième instruction.
L'exemple 1 utilise le compteur pour sortir à chaque boucle la valeur actuelle
de $i sous sa forme hexadécimale. La requête if($i % 8 == 0)
contient une division modulo et fait en sorte qu'après 8 sorties, une nouvelle
ligne soit commencée. La sortie proprement dite a lieu à l'aide de la fonction
printf (conforme à C), qui permet des sorties formatées
proprement sur le périphérique de sortie standard. Cette fonction n'est en réalité
pas très appropriée aux objectifs CGI (donc pour des sorties sous forme HTML).
L'exemple n°2 ci-dessus montre un cas Perl typique d'utilisation de la
boucle for. Cette forme est très pratique pour traiter dans l'ordre l'un
après l'autre les éléments d'une liste
ou d'un
hash.
Dans l'exemple 2, une liste @Alphabet est définie avec toutes les
majuscules de l'alphabet. Avec l'instruction for(@Alphabet), une boucle
est fixée pour la liste. La boucle tournera automatiquement aussi souvent que la
liste contient d'éléments. Pour adresser l'élément de la liste respectivement
actif, la
variable
prédéfinie $_ est employée dans la boucle. Dans cette variable est sauvegardé le
contenu de l'élément de liste respectivement actuel.
Une autre construction Perl typique c'est la boucle avec foreach.
Dans l'exemple n°3 ci-dessus, une telle boucle est mise en oeuvre. Dans ce type
de boucle est défini comme condition de la boucle un passage sans équivoque,
par exemple (de nombre..à nombre) ou des lettres (de lettre..à lettre). La
boucle tournera automatiquement aussi souvent que tous les éléments du passage
défini soient traités.
Si vous voulez mettre en place un compteur dans une boucle pour la
procédure désirée, vous pouvez définir une variable compteur entre foreach
et la condition de la boucle, comme dans l'exemple 3 ci-dessus la variable scalaire simple
$i.
L'exemple ci-dessus sort tous les chiffres entre 1 et 100 qui sont impairs et
divisibles par 3. Pour ceci, la commande
de saut next prête son aide.
![]() ![]() |
Une opinion courante au sujet de Perl est que l'on ne peut pas programmer
proprement de façon structurée avec. Certes, Perl met bien à disposition tout
ce qui est nécessaire à une programmation structurée et même à une
programmation orientée sur l'objet. Cependant, Perl est et reste un langage pour les
scripts, dont les programmeurs ne se donnent souvent pas la peine de
partager le déroulement en sous-programmes
distincts. Une alternative à la programmation structurée utilisée fréquemment
est constituée par les commandes de saut à un autre endroit au
choix dans le programme. Même à l'intérieur de boucles, les commandes de saut
sont très appréciées, pour forcer par exemple le passage à la boucle suivante
ou pour interrompre une boucle.
#!/usr/bin/perl # Devinez donc quel est le nombre donné par $i à la fin comme résultat $i = 1; goto resultat; while($i < 1000) { ++$i; if($i % 3 == 0) { redo; } elsif($i % 7 == 0) { next; } elsif($i % 13 == 0) { last; } } resultat: print "resultat: ", $i; |
#!/usr/bin/perl while($i < 10) { ++$i; if($i % 2 != 0) { redo; } } continue { print $i, "\n"; } |
Les commandes de saut suivantes sont disponibles en Perl:
goto saute à un autre endroit au choix dans le programme. Cet endroit doit cependant recevoir à cet effet une "étiquette" (comparable à une ancre dans un fichier HTML). Vous définissez une telle étiquette en notant un nom suivi de deux points. Dans l'exemple ci-dessus, est défini dans l'avant dernière ligne une étiquette nommée resultat:. Avec une commande goto comme au début de l'exemple, vous pouvez faire un saut à une telle étiquette.
redo est conçu pour une utilisation dans des boucles. Le parcours actuel de la boucle est interrompu. Le prochain parcours de boucle est lancé sans toutefois réévaluer la condition de la boucle. Si donc vous avez par exemple un compteur dans la condition de la boucle, La boucle redémarrera avec redo sans incrémenter le compteur.
next est également conçu pour l'emploi dans des boucles. Le parcours actuel de la boucle est interrompu. Le prochain parcours de boucle est lancé en évaluant la condition de la boucle.
last interrompt immédiatement une boucle.
continue est un cas spécial en Perl et se traite différemment qu'en C par exemple. L'exemple 2 ci-dessus montre un exemple d'utilisation typique. continue introduit un bloc d'instructions distinct, exactement comme une boucle. Dans ce bloc d'instructions, marqué comme d'habitude avec des parenthèses accolades { et }, vous pouvez noter des instructions de votre choix. Quand un tel bloc continue se trouve immédiatement derrière le bloc d'une boucle, il sera exécuté avec chaque passage de boucle. Avec une commande de saut comme redo dans le bloc d'instructions de la boucle, vous pouvez empêcher que le bloc continue soit exécuté. Dans l'exemple 2, on obtient avec cette construction que tous les chiffres pairs entre 1 et 10 soient sortis.
![]() | |
après:![]() |
![]() |
avant:![]() |
![]() |
SELFHTML/Quickbar
CGI/Perl
Éléments de langage Perl
Serge François, 13405@free.fr