Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Chapitre Les Scalaires

Télécharger au format docx, pdf ou txt
Télécharger au format docx, pdf ou txt
Vous êtes sur la page 1sur 6

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 3 caractères. On aura donc aucun mal à traiter des fichiers binaires en
Perl.

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 telsquels 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 :

est une chaîne comportant les caractères B o n j o u r \ et n, c'est-à-dire 9


'Bonjour\n'
caractères (notez que '\n' comporte 2 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 tels-
quels 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.

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 noterons bien qu'une variable est toujours précédée de son dollar même si
elle est à gauche d'un égal d'affectation.

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))...

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.

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), l'option -w provoquera un message
d'avertissement. Les 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 l'option -w !

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 suivant 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

affecte "\nruojnob" à $v. On rencontrera aussi cette fonction chez


$v = reverse("bonjour\n")
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 :

vaut on. La longueur peut être omise, dans ce cas toute la partie
substr("bonjour",1,2)
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 à ";

$vvaut 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 ; l'option -w provoquera un
message d'avertissement. Dans ce contexte, un nombre vaut la chaîne de sa représentation
décimale.

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 test (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 l'option -w permet souvent de repérer ces
situations.

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

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 :

 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 vrai 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 petit que $y,


 négative si $x est un nombre plus grand 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.

Vous aimerez peut-être aussi