FAQ PerlConsultez toutes les FAQ

Nombre d'auteurs : 18, nombre de questions : 250, dernière mise à jour : 29 octobre 2015  Ajouter une question

 

Bienvenue sur la FAQ Perl. Cette FAQ a pour vocation de vous enseigner ou de vous faire revoir les notions élémentaires de ce fantastique langage. Perl est très utilisé dans différents domaines depuis la gestion système, le réseaux, l'administration de bases de données, le web (CGI), la bureautique, la conception d'interfaces graphiques ou des contextes scientifiques telle la bioinformatique. Nous espérons que cette FAQ vous sera d'une grande utilité.

Vous souhaitez participer à l'amélioration de cette FAQ, n'hésitez pas !! Commentez

Bonne lecture !


SommaireS'initier à PerlScalaires (12)
précédent sommaire suivant
 

Une variable ou un scalaire (traduction impropre et systématique de l'anglais 'scalar' qui signifie "variable" ou "quantité variable") est le plus petit élément d'information que puisse traiter Perl. En Perl, un scalaire se repère au premier caractère de son identifiant (de son nom). Ce premier caractère est obligatoirement le symbole "dollar" ($). Le nom d'un scalaire peut être composé de chiffres, de lettres et de certains caractères spéciaux (_), mais il ne doit jamais commencer par un chiffre. On a coutume de dire qu'il s'agit d'un élément atomique, au sens où il n'est pas possible simplement de le diviser en éléments plus petits (du grec atomos qui signifie indivisible - "tomos" pour couper avec le préfixe privatif "a").

Mis à jour le 4 mai 2005 2Eurocents

Une variable scalaire peut contenir à peu près n'importe quoi, Perl étant un langage dit faiblement typé. Les langages faiblement typés ne font pas la différence, a priori, entre nombres entiers, nombres à virgule flottante, caractères et chaînes de caractères. Cela ne pose cependant pas de problème en Perl, ainsi qu'on le verra plus loin...

Mis à jour le 4 mai 2005 2Eurocents

Il suffit de l'utiliser, c'est-à-dire d'y faire référence en utilisant son identifiant (nom complet, avec le $ initial). Contrairement à de nombreux autres langages de programmation, Perl n'impose pas de déclaration préalable des variables. Ainsi, toute utilisation de variable crée automatiquement celle-ci. Pour pallier les nombreux risques que cette absence de déclaration des variables peut faire peser sur le développement, il existe des options permettant d'imposer une syntaxe stricte avec déclaration préalable à tout usage. Ainsi, pour plus de sécurité, il est préférable d'écrire, au début du script :

Code perl : Sélectionner tout
use strict;
On parle alors d'utiliser les "structures" - si quelqu'un s'oppose à ce barbarisme, qu'il parle maintenant ou se taise à jamais !!

Mis à jour le 4 mai 2005 2Eurocents

Les mots-clefs de déclaration de variables sont my et our.
Ces mots-clefs sont valables pour tous types de variable, et pas uniquement pour les variables scalaires. La différence entre my et our est abordée plus loin dans ce document. Dans l'immédiat, l'usage de my conviendra pour la plupart des cas. Ainsi, pour déclarer une variable $i, on écrira simplement :

Code perl : Sélectionner tout
my $i;

Mis à jour le 4 mai 2005 2Eurocents

L'opérateur d'affectation est tout simplement l'opérateur =. Ainsi, il est possible d'écrire :

Code perl : Sélectionner tout
my $i=0;
pour affecter une valeur initiale à la variable, dès son initialisation. Par la suite, on peut écrire :

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
$i = 5; 
  
# voire : 
my $j = $i; 
  
# ou bien : 
$i ='a'; 
$i ='test de chaîne'; 
$i =3.1415;
À l'issue de ces trois dernières affectations, $i vaut le caractère "a", pour la première, la chaîne "test de chaîne" pour la deuxième et 3.1415 (le nombre à virgule flottante) pour la troisième.

Les nombres peuvent être exprimés en
  • base décimale ($i = 100;) ;
  • octal (il suffit de commencer la valeur par un zéro : $i = 0144;) ;
  • hexadécimal (en commençant la valeur par un zéro suivi par un x : $i = 0x64;).

Mis à jour le 4 mai 2005 2Eurocents

Les variables auxquelles aucune valeur n'a été affectée sont initialisées automatiquement par l'interpréteur Perl.
La valeur implicite d'initialisation est une valeur spécifique un peu magique nommée "undef".

  • dans des opérations arithmétiques, elle vaut zéro ;
  • dans les opérations de chaînes de caractères, elle équivaut à la chaîne vide, mais attention, toutefois car son usage provoque des affichages de messages d'avertissement si les "warnings" sont actifs (use warnings; ) ;
  • il ne faut pas la tester de manière classique avec les opérateurs de comparaison (voir plus loin), mais au moyen d'une fonction spécifique : defined() qui retourne vrai si la variable est définie et faux si elle vaut undef ;
  • il est possible de l'affecter soi-même à une variable déjà définie, soit par une affectation $variable=undef; soit par une fonction undef($variable).

Mis à jour le 4 mai 2005 2Eurocents

Les principaux opérateurs arithmétiques sont disponibles. Ainsi, il est possible d'utiliser :

  • + pour l'addition ($a = $b + 75;) ;
  • - pour la soustraction (l'opérateur - existe aussi en version "unaire", pour signifier un nombre négatif) ($a = -75 -$b;) ;
  • * pour la multiplication ($a = $b * $c;) ;
  • / pour la division ($a = 83 / 17;) ;
  • % pour le modulo (reste de la division entière) ($b = 83 % 17;) ;
  • ** pour l'exponentiation (l'élévation à une puissance, comme $a = $b ** 3;) ;
  • ++ est un opérateur (unaire) de pré- ou post incrémentation de la variable sur laquelle il porte (++$a ou $a++) ;
  • -- est un opérateur (unaire) de pré- ou post décrémentation de la variable sur laquelle il porte (--$a ou $a--).

Il existe aussi des opérateurs spécifiques aux traitements sur les chaînes de caractères :

  • . (le point) est l'opérateur de concaténation de chaînes ($a = "abcd" . "efgh";) ;
  • x est l'opérateur de répétition qui répète la chaîne le précédant autant de fois qu'indiqué par le nombre suivant ([codeinline=perl]$a = "*" x 40;[codeinline=perl] pour obtenir quarante astérisques) ;
  • = est l'opérateur de mise en correspondance avec une expression rationnelle (gros chapitre du langage qui sera abordé ultérieurement).

Certains opérateurs sont qualifiés de "binaires bit à bit" :

  • ~ pour la négation bit à bit ($i = ~ $j;) ;
  • << est un opérateur de décalage bit à bit vers la gauche ($a = $b << 3;) ;
  • >> est un opérateur de décalage bit à bit vers la droite ($a = $b >> 3;) ;
  • & effectue un ET bit à bit entre ses opérandes ($zero = 0x36 & 0xC9;) ;
  • | pour un OU bit à bit ($deux_cent_cinquante_cinq = 0x36 | 0xC9;) ;
  • ^ pour un OU EXCLUSIF entre deux valeurs.

Il existe aussi des opérateurs de test, de comparaison, et ces opérateurs existent sous deux formes, selon que l'on souhaite comparer des nombres entiers ou bien des chaînes de caractères :

  • == ou eq pour tester l'égalité numérique ou alphabétique ;
  • < ou lt pour l'infériorité stricte ;
  • <= ou le pour l'infériorité ou égalité ;
  • > ou gt pour la supériorité stricte ;
  • => ou ge pour la supériorité ou égalité;
  • != ou ne pour la différence ;
  • <=> ou cmp sont des opérateurs spéciaux de comparaison, qui retournent -1, 0 et 1 selon lequel de leurs opérandes est le plus grand.

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/perl 
use warnings; 
use strict; 
  
my $nombre1 = 12; 
my $nombre2 = 22; 
  
my $comparaison1 = 12 <=> 21; 
my $comparaison2 = 21 <=> 12; 
my $comparaison3 = 12 <=> 12; 
my $comparaison4 = 'az' cmp 'zz'; 
my $comparaison5 = 'zz' cmp 'az'; 
my $comparaison6 = 'zz' cmp 'zz'; 
  
print "$comparaison1\n";    # -1 
print "$comparaison2\n";    # 1 
print "$comparaison3\n";    # 0 
print "$comparaison4\n";    # -1 
print "$comparaison5\n";    # 1 
print "$comparaison6\n";    # 0 
  
if ( 1 < 10 ) { 
  print "< : 1 est inférieur à 10\n"; 
} 
  
if ( 1 lt 10 ) { 
  print "lt : 1 est inférieur à 10\n"; 
}
Et enfin, des opérateurs logiques complètent la panoplie :

  • && ou and permettent de réaliser la conjonction entre deux conditions (le ET logique) ;
  • || ou or permettent de réaliser la disjonction entre deux conditions (le OU logique) ;
  • xor permet de réaliser une disjonction exclusive (le XOR logique) ;
  • ! ou not permettent de réaliser la négation d'une condition.

La différence entre les opérateurs logiques similaires vient, entre autres, des différences de priorité. Ils ne sont cependant pas toujours utilisés dans le même contexte. Notamment, l'usage des opérateurs logiques dans le style C (&&, ||) avec des listes (sujet abordé plus loin) risque de poser problème. Dans ce cas, l'usage des opérateurs en toutes lettres est plus sûr. Il existe encore d'autres opérateurs, dont les plus utiles sont :

  • ?: qui permet de réaliser un choix entre deux valeurs, selon le test d'une condition ($i = ($a == $b)?$a:$b; $i vaudra $a si $a et $b ont la même valeur, $b s'ils sont différents) ;
  • , qui procède à l'évaluation de son membre de droite, puis à celle du membre de gauche, avant de garder le résultat de la dernière évaluation (ça parait compliqué et inutile, comme ça, mais quand on maîtrise bien, ça peut réellement être très puissant) ($i = ($j=100),($k=50); fait que $i et $j valent 100, $k vaut 50).

Et il existe aussi des formes abrégées des principaux opérateurs réfléchis (même variable présente des deux côtés de l'affectation). Ces opérateurs posent les mêmes difficultés de maintenance ou de compréhension du code qu'en C. On trouve : +=, -=, *=, /=, .=, <<=, etc.

Opérateur defined-or (depuis Perl 5.10):

Cet opérateur est //, à ne pas confondre avec ||. $x // $y équivaut à (defined $x ? $x : $y).
// vérifie si la variable $x est définie, si c'est le cas, il retourne $x sinon retourne $y.

$z //= $x; équivaut à if ( not defined $z ) { $z = $x; }
Voici un exemple de code

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/perl 
use warnings; 
use strict; 
  
my $x = 10; 
my $y = 20; 
my $z; 
my $age = $x // $y; 
print "Mon age : $age ans\n"; 
  
$age = $z // $y; 
print "Mon age : $age ans\n"; 
  
$z //= $x; # équivaut à if ( not defined $z ) { $z = $x; }  
print "\$z : $z\n";
Code : Sélectionner tout
1
2
3
Mon age : 10 ans 
Mon age : 20 ans 
$z : 10
Qu'elle est la différence par rapport à || et à quel moment, il est préférable d'utiliser // ?

Prenons l'exemple d'une procédure qui retourne une valeur. L'exemple suffira à la compréhension de l'opérateur.

Code perl : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/perl 
use warnings; 
use strict; 
  
sub doubler { 
  my $valeur = shift || 10; 
  my $double = ($valeur * 2); 
  print "$double\n"; 
} 
sub doubler_version2 { 
  my $valeur = shift // 10; 
  my $double = ($valeur * 2); 
  print "$double\n"; 
} 
  
doubler(17); # imprime 34 
doubler();   # imprime 20 
doubler(0);  # imprime 20 <= Attention, piège  
print "============\n"; 
doubler_version2(17); # imprime 34 
doubler_version2();   # imprime 20 
doubler_version2(0);  # imprime 0 <= c'est mieux

Mis à jour le 4 mai 2005 2Eurocents djibril

Perl sait très bien faire la différence tout seul.
En fait, en fonction des opérateurs utilisés, Perl détermine automatiquement la façon dont il faut traiter le contenu des variables. C'est la notion de "contexte". Il existe deux contextes principaux : contexte scalaire et contexte de list.

Le contexte scalaire, lui, possède des nuances : contexte scalaire numérique, contexte scalaire de chaîne et contexte scalaire booléen.
Lorsque l'on utilise des opérateurs numériques ou des fonctions numériques (que l'on verra plus tard), Perl modifie automatiquement le contexte pour traiter les variables comme des nombres. Qui plus est, si l'un de ces nombres contient un . (le séparateur décimal), par exemple, tous les nombres en jeu dans l'opération sont automatiquement promus comme nombres flottants.
Attention toutefois, car l'évaluation de chaînes de caractères en contexte numérique peut provoquer des résultats inattendus. Ainsi, l'évaluation suivante peut tout à fait donner un résultat, qui s'il est cohérent du point de vue de Perl n'en est pas moins faux :

Code perl : Sélectionner tout
$i = "2eurocents" + "Code 100 sous 6"; print $i."\n";
produira 2, car "2eurocents" est évalué à 2 en contexte numérique et "code 100 sous 6" n'arrive pas à être évalué (le premier mot n'est absolument pas numérique).

Code perl : Sélectionner tout
$i = "2eurocents" + "100sous6"; print $i."\n";
produira 102, "2eurocents" est toujours évalué à 2 et "100sous6" est évalué à 100, c'est-à-dire à toute la portion numérique initiale de la chaîne.
Heureusement, l'interpréteur Perl peut nous aider par des messages d'avertissements lors de telles opérations, si la directive warnings a été utilisée (paramètre -w du shebang ou clause use warnings;). Cela peut être un avantage, comme un inconvénient. Il importe que le programmeur teste au préalable les cas où cela peut lui poser des problèmes de cohérence car le langage ne le fera pas pour lui. Ainsi, en Perl, il est possible de faire aussi bien :

Code perl : Sélectionner tout
$volume = "10 l" + "5 dm³";
qui est cohérent, que :

Code perl : Sélectionner tout
$melange = "3 choux" + "18 paires de carottes";
qui n'a absolument aucun sens, pour le plus grand bonheur pédagogique de toute une génération d'instituteurs. Heureusement, le programmeur sait ce qu'il fait, la plupart du temps... le vrai danger vient le l'utilisateur, tout le monde le sait ! En fait, ces préoccupations valent surtout pour les variables sur lesquelles l'utilisateur peut avoir le contrôle (zones saisies, données provenant de fichiers, etc.).

Mis à jour le 5 mai 2005 2Eurocents

Bien que Perl ne soit pas réellement performant dans le domaine du calcul numérique (on verra pourquoi d'ici peu), il est tout à fait possible de mener quelques opérations. Les opérateurs arithmétiques sont disponibles, on l'a vu, mais il y a aussi quelques fonctions :

  • abs() pour les valeurs absolues ;
  • atan2() pour la tangente inverse, ainsi que cos() et sin() pour les amoureux de la trigonométrie ;
  • log() et exp() pour le logarithme népérien et les puissances de e ;
  • sqrt() pour les racines carrées ;
  • int() pour tirer les parties entières ;
  • hex() ou oct() pour des changements de base numérique ;
  • rand() et srand() permettent d'utiliser et d'initialiser le générateur de valeurs pseudoaléatoires.

Mis à jour le 5 mai 2005 2Eurocents

Quoi, les chaînes de caractères ? En fait, en Perl, les chaînes de caractères sont des scalaires comme les valeurs numériques. Pour être parfaitement rigoureux, on devrait même dire que les valeurs numériques sont des scalaires comme les chaînes de caractères !
En effet, Perl stocke toutes ses variables sous la forme de chaînes, ainsi que les programmeurs expérimentés peuvent s'en apercevoir en manipulant les fonctions pack/unpack... Perl ne fait même pas la différence entre caractères imprimables ou valeurs binaires : tout cela constitue des valeurs scalaires valides.

Mis à jour le 5 mai 2005 2Eurocents

Une chaîne de caractères est un scalaire dont la valeur est exprimée entre quotes. Nos claviers étant généreusement dotés de simple comme de double quote, nous avons le choix de l'expression.
Lorsque la chaîne de caractères est exprimée entre doubles quotes, l'interpréteur Perl poursuit son travail à l'intérieur et y interprète ce qu'il y rencontre. Il est ainsi possible d'y insérer des éléments tels que d'autres scalaires (préfixés par un $), des caractères spéciaux exprimés en notation "back slash" (tels que \n pour le saut de ligne, \r pour le retour de chariot, \t pour la tabulation...), etc.

Code perl : Sélectionner tout
1
2
3
$monde = "world !\n"; 
$politesse = "Hello $monde"; 
print $politesse;
Dans le cas où l'on souhaiterait accoler un scalaire et du texte fixe dans une chaîne de caractères, sans espace intermédiaire, il est nécessaire d'exprimer le scalaire différemment afin d'aider Perl à trouver les limites de son nom. On met ainsi le nom du scalaire entre accolades :

Code perl : Sélectionner tout
1
2
3
4
5
6
7
$racine = "programme"; 
$_1e_pers_sing = "Je ${racine}e"; 
$_2e_pers_sing = "Tu ${racine}es"; 
$_3e_pers_sing = "Il ${racine}e"; 
$_1e_pers_plur = "Nous ${racine}ons"; 
$_2e_pers_plur = "Vous ${racine}ez"; 
$_3e_pers_plur = "Ils ${racine}ent";
Il est possible de bloquer le travail d'interprétation de Perl en protégeant certains caractères par une barre oblique inversée. Ainsi, pour insérer des doubles quotes, un dollar, une arobas ou une barre inversée, il faut exprimer respectivement \", \$, \@ et \\.
De la même manière, pour exprimer certains caractères spéciaux dont on connait le code ASCII, il est possible d'exprimer ce dernier numériquement, à la suite d'un antislash : \0 (caractère NULL) ou \7 (caractère BELL) par exemple. Lorsque la chaîne est exprimée entre simples quotes, l'interpréteur Perl la prend telle quelle, sans examiner son contenu. Seuls les caractères ' et \ ont besoin d'y être protégés (' doit être écrit \', pour ne pas être confondu avec la fin de chaîne, et \ doit être protégé en \\ puisqu'il peut avoir un rôle spécial dans la protection de ').
Ainsi, "col1\tcol2\tcol3\n" représente un texte de trois colonnes séparées par des tabulations et terminé par un saut de ligne.
'col1\tcol2\tcol3\n' représente ce texte tel quel, avec les \, les t qui les suivent et le n final.

Mis à jour le 5 mai 2005 2Eurocents

La vraie puissance de Perl, on le dit souvent, réside dans le traitement des chaînes de caractères. C'est particulièrement vrai dans l'application des expressions rationnelles, qui seront vues ultérieurement. Hors ce gros morceau du langage, de nombreux traitements sont possibles, que ce soit par le biais des opérateurs ou par des fonctions spécifiques :

  • l'opérateur de concaténation : "Bonjour "."le monde" ;
  • l'opérateur de multiplication : "Bonjour " x 3 ;
  • chop() supprime et renvoie le dernier caractère d'une chaîne de caractères ;
  • chomp() supprime le dernier caractère d'une chaîne, uniquement s'il s'agit d'une fin de ligne (mais ne renvoie pas celui-ci !) ;
  • reverse() retourne une chaîne de caractères (aimez-vous les palindromes ?) ;
  • uc(), lc(), ucfirst() et lcfirst() sont des fonctions de changement de casse des chaînes passées en paramètre. uc() passe la chaîne en majuscules (upper case) et lc() en minuscules. Les variantes *first ne traitent que la première lettre ;
  • oct() et hex() font des conversions de bases numériques. Ah, mais on en a déjà parlé quand on évoquait des fonctions numériques... Oui, mais en Perl, tout est chaîne de caractères, donc en fait, les fonctions numériques travaillent sur des chaînes qu'elles convertissent pour le traitement ;
  • chr() et ord() font des conversions code ASCII/caractère. Ainsi, chr(65)="A" et ord("A")=65 ;
  • length(), index(), rindex() et substr() sont des fonctions classiques de traitement de chaînes.
    La fonction length() renvoie la longueur de la chaîne.
    Les fonctions index() et rindex() renvoient la position de la première ou de la dernière occurrence d'une sous-chaîne dans une chaîne, avec éventuellement une position de début de recherche. substr() retourne une portion d'une chaîne donnée, à partir d'une position fixée et d'une longueur précisée.
    Cette dernière fonction, substr() est intéressante à plus d'un titre car elle peut aussi servir à faire un remplacement de portion de chaîne, éventuellement de longueur variable.

    Elle est utilisée, dans ce cas, comme réceptacle d'une affectation : my $chaine="Bonjour tout le monde"; substr ($chaine, 3, 4) = " appétit"; remplace "jour" (position 3, longueur 4 dans la chaîne) par " appétit ". La chaîne est agrandie et tout est pour le mieux ;
  • pack() et unpack() sont des fonctions très avancées qui permettent toutes sortes de codages et décodages de valeurs binaires, décimales, hexadécimales, tant sur des nombres que sur des chaînes. Elles sont très utilisées dès que vous avez à coder/décoder des valeurs binaires provenant de dialogues directs avec différents matériels, protocoles, systèmes...
  • print(), printf() et sprintf() sont, bien sûr, des fonctions de dialogue. Elles permettent de dialoguer aussi bien avec la console, qu'avec des fichiers. La fonction print affiche simplement ses paramètres, là où les fonctions printf et sprintf permettent des formatages complexes, comme leurs homologues en C dont elles sont issues ;
  • tr/// (ou y///) est une fonction spéciale permettant de transformer, dans une chaîne, tous les caractères d'un ensemble en caractères d'un second ensemble. Elle est apparentée aux expressions rationnelles.

D'autres fonctions sont disponibles, pour traiter toutes sortes de scalaires, et lorsque ce n'est pas suffisant, le langage peut être étendu par l'usage de modules, ainsi qu'on le verra par la suite.

Mis à jour le 5 mai 2005 2Eurocents

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

 
Responsable bénévole de la rubrique Perl : djibril -