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.
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.
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
.
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.
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))...
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 :
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;
!
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.
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 :
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érique | de 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 :
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 :
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.