wiki:InsiaProgPerlIf

Sommaire

Programmation Perl - Tests (if, until, ...)

1. If, else, elsif

La structure des tests et des expressions booléennes en Perl est une fois de plus très similaire à ce que l'on trouve en C:

if ($i > 0) {
  print "$i est strictement positif\n";
}

Comme pour les boucles, on peut également profiter de l'inversion de la syntaxe: dans ce cas le bloc disparait au profit d'une seule instruction, et les parenthèses deviennent également facultatives:

print "$i est un entier strictement positif\n" if $i < 0;

Pour proposer une branche alternative:

if ($i >= 0) {
  print "$i est positif";
} else {
  print "$i est négatif";
}

Par contre si l'on veut évaluer plusieurs branches (exclusives) en cascade, il y a le mot clé spécifique elsif:

if    ($i  > 0) { print "$i est strictement positif"; }
elsif ($i == 0) { print "$i est nul"; }
else            { print "$i est négatif"; }

C'est une erreur de syntaxe d'utiliser la construction else if...! Ce choix de langage est principalement issu du C où la distinction des imbrications ou des cascades sont la plupart du temps délicates:

2. Opérateur ternaire

Encore un emprunt du C, il doit son nom à sa spécificité: c'est le seul opérateur utilisant 3 opérandes. Cette expression:

my $signe = ($i >= 0) ? "positif" : "négatif";

... est équivalente à cette construction:

my $signe;
if ($i >= 0) { $signe = "positif"; } else { $signe = "négatif"; }

3. Expressions booléennes

Opérateurs de comparaison

On retrouve la gamme des opérateurs classiques, mais il existe en général une version opérant dans le domaine numérique, tandis que l'autre considèrera ses opérandes comme des chaînes de caractère:

Numérique Chaîne Description
< lt strictement inférieur
<= le inférieur ou égal
> gt strictement supérieur
>= ge supérieur ou égal
== eq identique
!= ne différent
<=> cmp comparaison (pour le tri)

Quelques exemples illustrant la différence entre les deux contextes:

Numérique Chaîne
"a" < "b" est faux "a" lt "b" est vrai
"-1.5" < "1" est vrai "-1.5" lt "1" est faux

Notes sur cmp et <=>: ces opérateurs sont utiles pour définir une relation d'ordre entre des éléments d'une liste, et donc en particulier les trier. Ce type d'opérateur se comporte comme suit:

Si... Alors $a <=> $b vaut
$a < $b -1
$a == $b 0
$a > $b 1

Valeurs booléennes des scalaires

Parfois on prend des raccourcis et on convertit un scalaire directement en valeur booléenne. Il existe donc une convention pour savoir si un scalaire est vrai ou faux:

  • si le scalaire n'est pas défini ou est une chaine vide, il est faux
  • si le scalaire est un entier nul, il est faux
  • dans tous les autres cas il est vrai

Exemples:

Valeur scalaire Valeur booleenne
undef faux
0 faux
"" faux
"0" faux
"00000" vrai
"bonjour" vrai
-5 vrai

Note: le contexte d'une expression booléenne est toujours scalaire, donc une liste sera considérée comme son nombre d'éléments.

Opérateurs logiques

On peut combiner le résultat des tests précédents, ou des valeurs booléennes tels que décrites ci-dessus à l'aide des opérateurs logiques similaires au C, doublés de leur nom en clair (comme en shell):

Opérateur Description
&&, and ET logique
||, or OU logique
xor OU exclusif logique
!, not négation logique (opérateur unaire)

Evaluation partielle

Cette technique est très populaire en Shell, et également parfois utilisée en programmation C. Elle repose sur le fait que les opérations logiques ET et OU peuvent avoir un résultat défini avec la valeur d'une seule opérande dans certains cas:

  • A and B: si A est faux, alors le résultat est faux (B n'est pas évalué)
  • A or B: si A est vrai, alors le résultat est vrai (B n'est pas évalué)

On trouve ainsi très souvent ce genre de construction en Perl:

open(FILE, "<source.txt") or die("Erreur d'ouverture ($!)");

Comme la plupart des fonctions Perl renvoient un état booléen dépendant de leur bonne exécution, la partie droite or die... n'est évaluée que si la partie gauche est fausse.

4. Tests sur les fichiers

Perl a emprunté les facilités du Shell pour effectuer des tests directement sur des fichiers, ce qui est très pratique et évite d'utiliser une bibliothèque de programmation fastidieuse (se référer à file test dans man perlfunc). Exemple:

my $file = "source.txt";
die "Fichier $file non présent" if (!-e $file);

Pour référence, voici les tests extrait de la documentation de Perl:

-r File is readable by effective uid/gid.
-w File is writable by effective uid/gid.
-x File is executable by effective uid/gid.
-o File is owned by effective uid.
-R File is readable by real uid/gid.
-W File is writable by real uid/gid.
-X File is executable by real uid/gid.
-O File is owned by real uid.
-e File exists.
-z File has zero size (is empty).
-s File has nonzero size (returns size in bytes).
-f File is a plain file.
-d File is a directory.
-l File is a symbolic link.
-p File is a named pipe (FIFO), or Filehandle is a pipe.
-S File is a socket.
-b File is a block special file.
-c File is a character special file.
-t Filehandle is opened to a tty.
-u File has setuid bit set.
-g File has setgid bit set.
-k File has sticky bit set.
-T File is an ASCII text file (heuristic guess).
-B File is a "binary" file (opposite of -T).
-M Script start time minus file modification time, in days.
-A Same for access time.
-C Same for inode change time (Unix, may differ for other platforms)
Last modified 8 years ago Last modified on Nov 12, 2012, 1:31:32 PM