(Se reporter à la section
C'est la variable de base. La variable scalaire se préfixe du
$ (comme les variables shell). Elle peut prendre pour
valeur un entier, une chaîne de caractères ou une référence.
$number = 1; # un entier
$string = "Il fait beau"; # une chaine de caractères
$reference = \$number; # une référence sur l'entier 1
$i = "1"; # la chaine "1"
$i ++ # 2
$i = "$i" # la chaine "2"
Perl effectue les conversions implicites des valeurs des variables
scalaires pour que les opérations qui les affectent puissent
être exécutées.
$phrase = "2*2 = 4" . "et sqrt(4) = 2" . ".\n"; # concatenation 1
Le caractère . permet de concaténer des chaînes
entre elles.
$phrase = "2*2 = ", 2*2, " et sqrt(4) = ", sqrt (4), ".\n"; # concatenation 2
La virgule permet de concaténer les évaluations des routines
présentes sur la ligne d'affectation. Ainsi la variable scalaire
$phrase contient la chaine "2+2 = 4 et sqrt(4) =
2.".
Préfixé du caractère @, le tableau appelé aussi table ou liste
est un ensemble de variables scalaires. Donc une table peut contenir
des entiers, des chaînes de caractères, des références et
même des tables. Pour définir une table on utilise les
parenthèses et on sépare les éléments par une virgule.
(a, b, c) # une table de caractères
@tab = ( 1, 2, 3) # une table d'entiers
@foo = ( 1, b, $var) # une table avec des éléments de
# types différents
Une table est indexée par des entiers. Le premier indice d'une table
est 0. Le premier élément de la table @tab se nomme
$tab[0]. Le dernier élément de la table est
$#tab. Le nombre d'éléments de la table peut donc s'écrire
$#tab + 1
@tab = (a, b, c);
$tab[0]; # a
$tab[1]; # b
$#tab; # 2
$tab[ $#tab ] # c
$#tab + 1 # 3
(Se reporter à la section
Ces fonctions permettent de manipuler la table comme une pile. La
fonction pop retourne le dernier élément de la table et le
supprime. push ajoute un élément à la fin d'une table.
shift retourne le premier élément d'une table et le supprime.
unshift insere un élément au début d'une table.
Voici quelques exemples d'utilisation de ces fonctions.
@tab = ('Larry', 'WALL');
$age = '24';
push(@tab, $age); # @tab = ('Larry', 'WALL', '24')
print shift(@tab); # affiche 'Larry' et
# @tab = ('WALL', '24')
print pop(@tab); # affiche '24' et
# @tab = ('WALL')
La commande sort trie les éléments d'une table et retourne la
liste triée.
@tab = ('b', 'w', 'a', 't');
@tab = sort @tab; # @tab = ('a', 'b', 't', 'w')
La commande reverse retourne la liste des éléments dans l'ordre
inversé.
@tab = reverse @tab; # @tab = ('w', 't', 'b', 'a')
split permet de découper une chaîne de
caractères. C'est une fonction puissante car c'est
l'utilisateur qui spécifie quel caractère ou quelle expression
régulière (voir chapitre sur les expressions
régulières) permet de délimiter les
éléments à découper. La commande retourne une liste contenant
les éléments de la chaîne découpée.
@tab = split(/\+/, "1 + 2 + 3"); # @tab vaut (1, 2, 3)
Ici le caractère de séparation est +. Si on avait voulu
découper une chaîne contenant des + et des - on aurait
utilisé l'expression régulière suivante : /+|-/
qui veut dire "+ ou -".
join regroupe les éléments d'une table dans une chaîne de
caractères en les séparant par la chaîne de
caractères donnée en argument. La chaîne de
caractères peut être annotée comme une expression
régulière ou entre guillements.
print join(/ - /, @tab); # affiche '1 - 2 - 3';
print join(" - ", @tab); # idem
Une fonction de hash permet de calculer une clé (unique si possible)
à partir d'une chaîne de caractères. La clé de
valeur entière permet d'indexer une table par la suite. Cette
technique est appelée
La forme générale d'une table de hash est:
%hash = ( cle1, val1, cle2, val2, ..., cleN, valN);
%hash = (nom, WALL, prenom, Larry);
L'exemple montre une table avec deux éléments. La valeur associée à
la clé prenom est Larry. De même la valeur associée à la
clé nom est WALL.
Cette notation est maintenant obsolète et peu lisible. Une nouvelle
écriture permet de ne pas confondre la table de hash avec une liste.
%hash = (
'nom' => 'Larry',
'prenom' => 'WALL',
);
$hash{'nom'} # Larry
$hash{nom} # Larry
$hash{prenom} # WALL
On remarque que lorsque la clé est constituée d'un seul mot il n'est
pas nécessaire de la mettre entre apostrophes (ou
Les exemples des fonctions que nous allons décrire seront basés sur la
table de hash suivante:
%hash = (
'nom' => 'FORCIOLI',
'prenom' => 'Alain',
'age' => '24',
);
keys retourne une liste (table) contenant les clés de la table de
hash.
@k = keys %hash; # @k = ('nom', 'prenom', 'age')
@k = sort keys %hash; # @k = ('age', 'nom', 'prenom')
values à l'inverse de keys retourne une liste de
toutes les valeurs des clés. L'obtention d'une telle liste ordonnée
se fait de cette manière.
@v = sort values %hash; # @v = ('24', 'Alain', 'FORCIOLI')
each retourne le premier couple de la table de hash sous la forme
d'une liste. Le couple est ensuite supprimé de la table de hash.
($nom, $val) = each %hash; # $nom = 'nom'
# $val = 'FORCIOLI'
# keys %hash = ('prenom', 'age')
delete supprime la valeur associée à la clé donnée en
argument.
delete $hash{'age'}; # keys %hash = ('prenom')
exists retourne 1 (vrai) si une valeur existe pour une clé
donnée.
print "Exists\n" if exists $hash{'prenom'}; # affiche
# 'Exists\n'
(se reporter à la section
$/; # Le caractère séparateur de ligne
# '\n' par defaut.
$_; # le contenu de l'entrée standard ou la valeur de
# chaque élément d'une table dans une boucle foreach
# ou while.
@_; # un tableau contenant les arguments d'une fonction;
%ENV; # une table de hash qui contient les variables
# d'environnement du shell.
# Equivalent a la commande 'env'.
@ARGV; # une table des arguments du script Perl.
Comme tout langage de programmation, Perl dispose de structures de contrôle.
if(expr)
{
block1
} else
{
block2
}
ou
if(expr)
{
block1
} elseif(expr2)
{
block2
}
Dans les deux cas block1 est exécuté si l'évaluation de
if($a == "a")
{
print "$a\n";
} elseif($a == "b")
{
print "$a$a\n";
} elseif($a == "c")
{
print "$a$a$a\n";
} ...
foreach (table)
{
block;
}
while(expr)
{
block;
}
La structure de contrôle foreach permet d'executer
block autant de fois qu'il y a d'éléments dans table.
@tab = (1, 2, 3, 4, 5);
$i = 0;
foreach (@tab)
{
print "$i\n";
$i++;
}
L'exemple ci-dessus affiche successivement les valeurs 0, 1, 2, 3 et
4. Nous avons vu dans la section Les variables
speciales que la variable $_ prenait la
valeur de chaque élément d'une table passée dans une boucle
foreach ou while. Illustrons cette particularité en
simplifiant l'exemple précédent.
@tab = (1, 2, 3, 4, 5);
foreach (@tab)
{
print "$_\n";
}
Cette fois, l'exemple affiche 1, 2, 3, 4 et 5. $_ prend
successivement chaque valeur des éléments de \@tab.
Encore plus simple :
foreach (1 .. 5)
{
print "$_\n";
}
(1 .. 5) est un intervalle en Perl.
@tab = (1, 2, 3, 4, 5);
while($i = shift(@tab))
{
print "$i\n";
}
shift retourne le premier élément de la table @tab et le
supprime. Ainsi $i prend successivement les valeurs 1, 2,
3, 4 et 5. La boucle s'arrête lorsque $i est vide c'est à dire
lorsqu'il n'y a plus d'éléments dans @tab.
Perl dispose de quelques artifices permettant de rendre plus lisible
le code écrit.
print $value if $value;
Le contenu de $value est affiché si la variable est définie.
Cela évite d'avoir
if($value)
{
print $value;
}
De même:
print $value unless ! $value;
Littéralement, on affiche la valeur de $value A MOINS QUE
la variable ne soit pas définie (! est l'opérateur non). Pour
être encore mieux compris d'un humain, on aurait pu écrire:
print $value unless ! defined $value;
De la même manière, on peut aussi utiliser while.
print "/tmp/lock: exists\n" while -f "/tmp/lock";
La structure générale d'une fonction est:
sub fonction
{
# block
}
block est le corps de la fonction, c'est à dire les
actions à exécuter. Chaque action est séparée d'une autre par
';'. Le caractère '#' permet de commenter le code
écrit. Tout ce qui suit ce caractère jusqu'au prochain retour
à la ligne n'est pas interprété.
sub hello
{
print "Hello World !\n";
}
hello(); # affiche 'Hello World !\n'
hello; # idem
&hello; # idem
do hello; # idem
L'exemple précédent nous montre comment créer une fonction et comment
l'exécuter de quatre manières différentes.
sub true
{
return 1;
}
$t = true; # $t vaut 1;
$t = true(); # idem
La fonction suivante est équivalente:
sub true
{
1;
}
$t = true; # $t vaut 1
Les deux exemples ci-dessus sont équivalents. En fait Perl retourne la
valeur de la dernière expression de la fonction
exécutée. Cette valeur n'est pas seulement entière. Il
est possible de retourner des tables ou des tables de hash.
sub foo
{
...
...
@tab = (1, 2, 3);
return @tab; # ou return (1, 2, 3);
}
sub bar
{
...
...
%hash = (
'i' => 1,
'ii' => 2,
);
%hash;
}
Losque
Les arguments d'une fonction se présentent sous la forme d'une table.
Elle est notée @_. Donc:
$_[0]; # premier argument.
$_[$#_]; # dernier argument :
# $#_ est le dernier indice dans le tableau
Bien souvent on connait à l'avance le nombre d'arguments d'une
fonction. Aussi on privilégiera l'usage de @_ à
$_[0], etc.
sub sum
{
$sum = 0;
foreach (@_) # parcours de tous les arguments
{
$sum += $_;
}
$sum;
}
sum(10, 20, 30, "40"); # retourne 100
sub hello
{
($nom, $prenom) = @_;
print "Hello $nom $prenom\n";
}
hello("FORCIOLI", "Alain"); # affiche 'Hello FORCIOLI Alain\n'
Cet usage est préférable car il évite une ligne complexe du genre:
($nom, $prenom) = ($_[0], $_[1]);
Il existe deux fonctions qui permettent de rendre locale une variable.
$a = "a";
{
local($a) = "b"; # $a est locale au 'scope'
# (par exemple: {...})
print "$a\n"; # affiche 'b\n'
}
print "$a\n"; # affiche 'a\n'
L'exemple précédent montre que les variables $a ont des
valeurs différentes. La seconde déclaration (utilisant local()
pour définir $a) rend $a visible uniquement à
l'intérieur des crochets. Nous avons deux espaces de noms en notre
présence. Dans le premier nous avons $a valant a,
dans le second nous avons $a égale à b.
Le manuel (section
(Voir la section
Les expressions régulières sont des caractères permettant de coder
n'importe quelle entité écrite appartenant à un ensemble (ex:
les décimales, les majuscules, les mots commencant par
[a-z]
[ ] permet de définir un ensemble de caractères. Le
caractère - signifie que l'ensemble contient la lettre a, b, c,
... ou z. On aurait pu écrire:
[abcdefghijklmnopqrstuvwxyz]
/[a-z]/
Voici une rapide description de quelques caractères d'expression
régulières.
. # n'importe quel caractère alphanumérique et
# d'espacement.
+ # fait correspondre au moins 1 fois ou plusieurs ce
# qui précède
? # 0 ou au plus 1 caractère de ce qui précède
# a? permet de faire correspondre '' ou 'a'
* # 0 ou plusieurs caractères de ce qui précède
# a* peut faire correspondre '', 'a', 'aa', 'aaa', etc...
[] # un intervalle
[^] # un complément
^ # qui commence par
$ # qui finit par
() # Définit un groupe de caractères réutilisable
| # ou
Perl étend le jeu de caractères des expressions.
\s # n'importe quel caractère d'espacements
\S # le complément de \s
Perl permet de modifier le traitement des chaînes par des
options, en passant une ou plusieurs lettres après le
/ final de l'E.R :
i # les majuscules sont traitées comme des minuscules
m # traite la chaine de caractères commes si elle était
# constituée de plusieurs lignes
s # traite la chaine comme si elle était sur une seule
# ligne
Deux opérations sont principalement utilisées par les expressions
régulières. La substitution et le
s/source/target/options
s signifie substitution. / est le séparateur
d'expression. Si une chaîne lue correspond à
#! /usr/bin/perl
while(<>)
{
s/^(.*)$/uc($1)/e;
$_;
}
On peut tester cette opération de la façon suivante:
$ uc.pl /etc/passwd
Le fichier /etc/passwd s'affiche avec uniquement des caractères
majuscules.
Le programme wc.pl suivant effectue le meme travail que la commande
unix, à savoir comptabiliser le nombre de caractères, de
lignes et de mots d'un fichier donné en argument (fichier wc.pl):
#! /usr/bin/perl
# Retourne le nombre de mots dans une ligne par mot on comprendra tous
# ce qui n'est pas 'espace'.
sub compte_mot
{
my($ligne) = @_;
$ligne =~ s/\s+/ /g;
my(@tab) = split( /\s/, $ligne);
$#tab;
}
sub compte_ligne
{
my($ligne) = @_;
return 1 if $ligne !~ /^\s*$/;
}
sub compte_char
{
my($ligne) = @_;
$ligne =~ s/\s//g;
length($ligne);
}
sub main
{
my($mots, $lignes, $chars);
while(<STDIN>)
{
$mots += compte_mot($_);
$chars += compte_char($_);
$lignes ++ if compte_ligne($_);
}
print "$ARGV[0]: w = $mots, l = $lignes, c = $chars\n";
}
main;
Exemple d'utilisation :
$ wc.pl /etc/passwd
Remarque: <STDIN> (equivalent à <>) est le flux de
l'entrée standard. <STDOUT> et <STDERR> ceux de la
sortie standard et d'erreur.
La référence Perl peut être vue comme le pointeur du langage C. C'est
une variable qui en référence une autre. Pour annoter la référence
sur la variable scalaire contenant la valeur 1, nous écrirons:
$i = 1; # i est une var. scalaire et vaut 1
$scalar_ref = \$i; # scalar_ref référence i.
Pour accéder au contenu pointé par la référence, il faut la
déréférencer. Perl utilise l'opérateur -> pour déréférencer
une référence.
Pour accéder à la valeur de la variable pointée il faut aussi la
déréférencer. De même qu'avec le langage C, une référence peut
int i = 3; int *ref_i = &i; *(ref_i) ++;
printf("i = %d\n", i);
$i = 3;
$ref_i = \$i;
$ref_i ++;
print $i, "\n";
La référence d'une table peut être créée de plusieurs façons:
@tab = (1, 2, 3);
$ref = \@tab;
ou
$ref = [1, 2, 3];
Pour déréférencer la table, il faut la préfixer du caractère qui
désigne la table en Perl : @
@tab1 = @$ref;
Pour parcourir les éléments de la table on peut écrire:
foreach (@$ref)
{
# $_ contient successivement 1, 2 et 3
}
On peut directement accéder à un élément contenu dans la table
pointée.
$ref->[0]; # vaut 1
$ref->[1]; # vaut 2
Pour obtenir le nombre d'éléments pointés :
$#{@$ref};
| -----
| |
| retourne la table et non une référence
| (1, 2, 3)
|
|
permet d'obtenir le nombre d'éléments d'une table.
L'expression précédente est équivalente à:
$#(1, 2, 3);
De même qu'avec la table il existe divers moyens de créer une
référence sur une table de hash.
%hash = (
'un' => 1,
'deux' => 2,
'trois' => 3,
);
$ref = \%hash;
ou
$ref = {
'un' => 1,
'deux' => 2,
'trois' => 3,
};
Pour déréférencer la référence il faut utiliser le caractère qui
désigne la table de hash : %.
%hash = %$ref;
Le parcours d'une telle référence peut se faire de la manière
suivante:
foreach $k (sort keys %$ref)
{
# $k vaut 'deux', 'trois' puis 'un'
}
foreach $v (sort values %$ref)
{
# $v vaut 1, 2 et 3
}
On peut modifier un élément pointé comme ceci:
$ref->{'un'} = 'UN';
On peut étendre une table de hash référencée.
$ref->{'quatre'} = 100;
On peut effacer un élément référencé:
delete $ref->{'un'};
Cette particularité est appréciable car elle permet entre autres de
faire de manière très simple de la génération de code dynamique.
Une référence sur une fonction s'écrit:
$func = sub {
# code de la fonction
};
Pour utiliser la fonction il faut la préfixer du caractère qui désigne
(historiquement) la fonction : \&.
&$func(); # lance la fonction
Le référencement/déréférencement permet à Perl de pouvoir créer des
structures de données complexes.
$a = [1, 2, 3];
$b = [
$a,
{
'un'=>1,
'deux'=>2,
},
];
$a référence la table (1, 2, 3). $b est
une référence sur une table qui contient deux éléments: $a
et une référence sur une table de hash ('un', 1, 'deux', 2).
$b->[0]; # vaut $a
@{$b->[0]}; # vaut (1, 2, 3)
${@{$b->[0]}}[0]; # vaut 1
$b->[0]->[0]; # idem
$b->[1]; # une référence sur une table de hash
$b->[1]->{'un'}; # vaut 1
sort keys %{$b->[1]}; # vaut ('deux', 'un')
On imagine très bien les immenses possibilités d'un tel
mécanisme. C'est d'ailleurs par ce biais que Perl permet de faire de
la programmation orientée objet.
Merci à :
Le langage Perl Copyright © 1998 Alain FORCIOLI This document is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This work is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this work; see the file COPYING. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.