Formation Perl - Formateur Perl

Formation de qualité par un spécialiste Perl

Sylvain Lhullier

Version 1.4.5
mars 2023


Guide Perl - Débuter et progresser en Perl

Dernière version sur  https://formation-perl.fr/guide-perl.html
© 2002-2023 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.

2. Les scalaires

Les scalaires sont le type de données atomique de Perl, dit autrement un scalaire est une donnée atome. Cela signifie que la granularité de données ne va pas au-delà.

Comme dit précédemment, une variable scalaire peut contenir une chaîne de caractères (String en Java et autres) ou un nombre (entier ou nombre à virgule flottante : int ou float en C, C++, etc.) ; je ne rentrerai pas dans l'explication de ce "ou". Voici des exemples de scalaires corrects : 12 "texte" 'texte' -3.14 3e9

Contrairement au C où le caractère \0 de code ASCII 0 (zéro) est le marqueur de fin de chaîne, en Perl les chaînes de caractères peuvent sans souci contenir ce caractère : "a\0f" est une chaîne comportant trois caractères. On n'aura donc aucun mal à traiter des fichiers binaires en Perl.

2.1. Les délimiteurs de chaînes de caractères

Les chaînes de caractères ont, comme en shell, principalement deux délimiteurs possibles : les doubles-quotes (") et les simples quotes ('). Elles n'ont pas le même rôle :

  • dans une chaîne délimitée par des doubles-quotes, le contenu est interprété :

    "Bonjour\n" est une chaîne suivie d'une fin de ligne. De la même manière "\t" est une tabulation (il existe d'autres caractères spéciaux).

    Dans "Bonjour $prenom" la variable $prenom est substituée par son contenu ; c'est-à-dire que ce scalaire contiendra la chaîne Bonjour, suivie d'une espace, suivie du contenu de la variable $prenom.

    S'il faut accoler un texte immédiatement après une variable, on utilisera les accolades pour délimiter le nom de la variable ; par exemple dans "il ${prefixe}donn$suffixe", c'est bien la variable $prefixe qui sera utilisée, puis la chaîne donn et enfin la variable $suffixe. On notera que ces accolades n'ont rien à voir avec celles des tables de hachage.

    Certains caractères doivent être "protégés" avec un anti-slash (\) si on veut les faire apparaître tels quels dans la chaîne de caractères ; ce sont les quatre suivants : " $ @ \. La chaîne "\$v" ne contient donc pas la valeur d'une supposée variable $v mais contient le caractère dollar et le caractère v ;

  • dans une chaîne délimitée par des simples quotes, aucune interprétation du contenu n'a lieu :

    'Bonjour\n' est une chaîne comportant les caractères B o n j o u r \ et n, c'est-à-dire neuf caractères (notez que '\n' comporte deux caractères).

    La chaîne 'Bonjour $prenom' ne comporte pas le contenu d'une hypothétique variable $prenom mais le caractère dollar suivi de la chaîne prenom.

    Puisque les variables ne sont pas substituées, les caractères à protéger sont moins nombreux. Le caractère ' a besoin d'être précédé d'un anti-slash pour apparaître tel quel dans une chaîne délimitée par de simples quotes. Il en est de même pour le caractère \ si celui-ci est suivi d'un autre caractère \

Les nombres n'ont quant à eux pas besoin de délimiteurs pour être manipulés : $x = 10.2 affecte le nombre 10,2 à la variable $x.

2.2. Déclaration et utilisation des variables

En Perl, il n'est pas obligatoire de déclarer les variables. Par défaut, l'usage d'une variable la crée ; si c'est un scalaire, elle aura la valeur undef (lire plus loin) ; s'il s'agit d'une liste ou une table de hachage, elle sera vide.

Pour d'évidentes raisons de relecture et pour éviter des erreurs bêtes, je vous conseille de toujours déclarer vos variables avant de les utiliser (sauf peut-être dans le cas de scripts de quelques lignes). Pour déclarer une variable, il nous faut utiliser my :

my $x;
my $y = 10;
my $z = "hello";

Nous venons ici de déclarer trois variables scalaires. Ces variables seront visibles (accessibles) dans toute la suite du bloc ainsi que dans les sous-blocs (comme en C) ; comme on s'y attend, elles ne le seront par contre pas dans les fonctions appelées depuis ces blocs. Le placement des déclarations est libre dans le bloc (comme en C++), il n'est pas nécessaire de les mettre en début de bloc.

Voici quelques exemples d'utilisation de variables (on suppose qu'elles sont déjà déclarées) :

$x = $y + 3;
$prenom = "Jules";
$phrase = "Bonjour $prenom";
print("$phrase\n");

Cette dernière ligne affichera à l'écran Bonjour Jules suivi d'un caractère de nouvelle ligne. Les habitués du shell noteront bien qu'une variable est toujours précédée de son dollar même si elle est à gauche d'un égal d'affectation.

2.3. La valeur undef

C'est une valeur particulière signifiant « non défini ». C'est aussi la valeur par défaut des variables scalaires non initialisées : my $x; est équivalent à my $x=undef; On peut affecter cette valeur à une variable après son initialisation : $x=undef; ou undef($x);

Si l'on veut tester qu'une variable scalaire vaut ou non undef, il faut utiliser la fonction defined : if(defined($x))... Ce test est vrai si $x est définie, c'est-à-dire si elle ne vaut pas undef. Une erreur classique est d'écrire : *incorrect* if($x!=undef) *incorrect* Ne surtout pas tenter de comparer une variable à undef, car cela ne fait pas ce qu'on attend.

La valeur undef est une valeur fausse pour les tests. Le test if( $x ) ... est faux si $x est non définie. Mais comme on le verra plus tard, il est également faux si $x vaut 0 (zéro) ou bien la chaîne vide. Donc un test if( $x ) ... est potentiellement dangereux. Pour tester si une variable est définie, une seule bonne façon : if(defined($x))...

2.4. Opérateurs, fonctions et contexte numériques

Sur les nombres, les opérateurs classiques sont disponibles : + - / * % ; ce dernier opérateur % est le modulo, c'est-à-dire le reste de la division entière du premier opérande par le second. Notez que la division effectuée par l'opérateur / n'est pas une division entière, mais une division réelle, cela même si ses opérandes sont entiers (2/3 vaut 0.6666...) ; si vous voulez effectuer une division entière, il vous faut tronquer le résultat de la division précédente avec int() : l'expression int($x/$y) vaut le quotient de la division entière de $x par $y (pour des nombres positifs).

Des raccourcis existent : += -= *= /= %=. Ces opérateurs sont à la fois une opération arithmétique et une affectation : $x+=3 est équivalent à $x=$x+3 mais en plus synthétique : on ajoute 3 à $x. L'instruction $y*=5 multiplie $y par 5.

Il existe aussi des auto-incrémenteurs et des auto-décrémenteurs : ++ et -- qui peuvent être placés avant ou après une variable : ils ajoutent ou déduisent 1 à cette variable. $x++ à le même effet que $x+=1 ou que $x=$x+1.

L'opérateur ** correspond à la puissance : 2**10 vaut 1024.

Les fonctions suivantes manipulent les nombres :

  • sin($x) cos($x) renvoient le sinus et le cosinus de $x.

  • exp($x) log($x) renvoient e puissance $x et le logarithme en base e de $x.

  • abs($x) renvoie la valeur absolue de $x.

  • sqrt($x) renvoie la racine carrée de $x.

Voici quelques règles de conversion en contexte numérique. Les chaînes de caractères représentant exactement un nombre sont converties sans problème ; "30" + "12" vaut 42. Dans tous les autres cas (énumérés dans ce qui suit), le pragma use warnings; provoquera un message d'avertissement. Les valeurs scalaires commençant par un nombre sont converties en ce nombre : "34.2blabla" vaudra 34,2. Les autres valeurs scalaires (y compris undef) sont converties en 0. Conclusion : utilisez toujours use warnings; !

2.5. Opérateurs, fonctions et contexte de chaînes

Les chaînes de caractères ont aussi leurs opérateurs. Le point (.) permet de concaténer deux chaînes : l'instruction $x="bon"."jour" a pour effet d'affecter la chaîne "bonjour" à $x (pas de gestion de la mémoire à effectuer). Cet opérateur est, entre autres cas, utile lorsque certaines parties de la chaîne sont les valeurs de retour de fonctions ; en effet, il suffit souvent d'utiliser les substitutions effectuées dans les chaînes délimitées par des doubles-quotes pour concaténer deux chaînes.

L'opérateur x est la multiplication pour les chaînes de caractères : "bon"x3 vaut "bonbonbon". Fort sympathique...

Les raccourcis suivants peuvent être utilisés : .= x= L'expression $x.=$y est équivalente à $x=$x.$y et concatène donc $y à la fin de $x.

Voici un certain nombre de fonctions utiles qui manipulent les chaînes de caractères :

  • length($x) renvoie la longueur de la chaîne $x. Par exemple length("bonjour\n") vaut 8 et length('bonjour\n') vaut 9 ;

  • chop($x) supprime le dernier caractère de la chaîne $x (la variable $x est modifiée). Ce caractère est renvoyé par la fonction : $c = chop($l); ;

  • chomp($x) supprime le dernier caractère de $x s'il s'agit d'une fin de ligne (la variable $x est modifiée). Cette fonction peut prendre plusieurs arguments, chacun subira un sort similaire. Ne pas écrire *incorrect* $x=chomp($x) *incorrect*, car chomp renvoie le nombre de caractères supprimés. Cette fonction nous sera très utile lorsque nous lirons des fichiers ligne à ligne ;

  • reverse($x) en contexte scalaire, renvoie la chaîne composée des caractères de $x dans l'ordre inverse. Par exemple $v = reverse("bonjour\n") affecte "\nruojnob" à $v. On rencontrera aussi cette fonction chez les listes (son comportement dépend du contexte) ;

  • substr($x,offset,length) vaut la sous-chaîne de position offset et de longueur length. Les positions commencent à 0 : substr("bonjour",1,2) vaut on. La longueur peut être omise, dans ce cas toute la partie droite de la chaîne est sélectionnée.

    Cette fonction peut être une lvalue, c'est-à-dire qu'on peut lui affecter une valeur (lvalue pour left-value : à la gauche du signe égal de l'affectation) :

    my $v = "salut toi";
    substr($v,5,1) = "ation à ";
    

    $v vaut alors "salutation à toi". C'est là que l'on se rend compte que Perl gère vraiment la mémoire tout seul !

  • index($chaîne,$sousChaîne,$position) renvoie la position de la première occurrence de $sousChaîne dans $chaîne. Le troisième paramètre, s'il est fourni, indique la position du début de la recherche ; sinon la recherche part du début de la chaîne (position 0) ;

  • rindex($chaîne,$sousChaîne,$position) effectue la même recherche que la fonction index, mais en partant de la fin de la chaîne (la recherche est effectuée de droite à gauche).

En contexte de chaîne de caractères, undef vaut la chaîne vide ; le pragma use warnings; provoquera un message d'avertissement. Dans ce contexte, un nombre vaut la chaîne de sa représentation décimale.

2.6. Les opérateurs de test

Les booléens (type de données ayant pour seules valeurs vrai et faux) n'existent pas en tant que tels en Perl, on utilise les scalaires pour effectuer les tests (comme C le fait avec les entiers). Il me faut donc préciser quelles sont les valeurs scalaires vraies et quelles sont les fausses.

Les valeurs fausses sont :

  • 0, c'est-à-dire l'entier valant zéro ;

  • "0" ou '0', c'est-à-dire la chaîne de caractères ne comportant que le caractère zéro (pas le caractère \0 de code ASCII zéro, mais 0 de code 48) ;

  • la chaîne vide :"" ou '' (ce qui est la même chose) ;

  • undef.

Toutes les autres valeurs sont vraies, par exemple : 1, -4.2, "blabla", etc. La plus originale est "00" qui vaut l'entier 0 dans les opérations numériques, mais qui est vraie...

Il existe deux catégories d'opérateurs de test : ceux pour lesquels on impose un contexte numérique aux opérandes et ceux pour lesquels on impose un contexte de chaîne de caractères. Par exemple == teste l'égalité de deux nombres (contexte numérique) et eq teste l'égalité de deux chaînes (contexte de chaîne). ("02"=="2") est vrai alors que ("02" eq "2") est faux. La différence est encore plus flagrante pour les opérateurs d'infériorité et de supériorité ; < teste l'ordre entre nombres, lt teste l'ordre ASCII entre chaînes ; donc (9<12) est vrai alors que (9 lt 12) est faux, car 9 est après 1 dans la table ASCII. Confondre ou mélanger ces deux types d'opérateurs est une erreur très courante que font les débutants, ainsi que les initiés qui ne font pas attention... Sachez que le pragma use warnings; permet souvent de repérer ces situations.

Voici un tableau décrivant les opérateurs de tests :

Tableau 1. 

contexte imposénumériquede chaînes
égalité==eq
différence!=ne
infériorité<lt
supériorité>gt
inf ou égal<=le
sup ou égal>=ge
comparaison<=>cmp

Les opérateurs booléens classiques sont présents :

  • expr1&&expr2 est vrai si expr1 et expr2 sont vraies (si expr1 est faux expr2 n'est pas évaluée) ;

  • expr1||expr2 est vrai si expr1 ou expr2 est vraie (si expr1 est vraie expr2 n'est pas évaluée) ;

  • !expr est vrai si expr est fausse.

Il existe aussi les opérateurs and or et not. Ceux-ci ont la même table de vérité que les précédents, mais sont d'une priorité plus faible.

Les deux opérateurs cités à la dernière ligne du tableau ne sont pas des opérateurs de test, mais des opérateurs de comparaison ; ils sont présents dans ce tableau en raison des similitudes qu'ils ont avec les opérateurs de test en ce qui concerne le contexte imposé aux opérandes. Ces opérateurs renvoient un nombre qui dépend de l'ordre entre leurs deux paramètres. L'expression ($x<=>$y) est :

  • positive si $x est un nombre plus grand que $y ;

  • négative si $x est un nombre plus petit que $y ;

  • nulle si $x et $y sont des nombres égaux.

Cet opérateur <=> est surnommé spaceship (vaisseau spatial en français) en raison de sa forme ;-)... Pour l'opérateur cmp, la comparaison se fait sur l'ordre des chaînes selon la table ASCII. Ces opérateurs seront fort utiles lorsque nous parlerons de la fonction sort qui effectue le tri des listes.


Contact © 1999-2024 formation-perl.fr
Formation Perl - Formation Perl intra entreprise - Formation Perl inter entreprise - Formateur Perl - Formateur Perl délégation
Formation Perl Formateur Perl Appartement à louer à Noisy-le-Grand Bric-à-Brac