Entrées et sorties - variables scalaires
 


Commencons par le plus simple, en lisant l'entrée standard et en affectant le résultat de cette lecture à une variable :

$inputline = <STDIN> ;

# lecture d'une ligne d'entrée

print($inputline) ;

# écriture de cette ligne


$inputline
constitue ce qu'on appelle une variable scalaire. Il faut noter que Perl est sensible à la casse des identifiants, de sorte que $a et $A ne désignent pas la même variable.

On peut aussi bien affecter un nombre ou du texte à une variable :
$a = 42 ;
$b = "Hello world" ;
$c = 17 + 5 ;
$d = $c +12 ;

Lors de la saisie d'une ligne du type
$inputline = <STDIN> ;
la variable $inputline contient le caractère de nouvelle ligne \n tapé à la fin, ce qui peut être gênant, surtout dans le cas d'une entrée numérique. Pour le supprimer, on utilise chop :
$inputnumber = <STDIN> ;
chop($inputnumber) ;

Lorsqu'on affecte la lecture d'un fichier entier à une variable, on peut supprimer tous les \n de fin de ligne de la manière suivante :
$/=undef;
$fichier_entier = <STDIN>;
$fichier_entier =~ tr/\n//d;
Voir le rôle de $/ dans le paragraphe consacré aux variables système.

Perl autorise la substitution des variables dans les chaînes de caractères encadrées par des guillemets :
$a = 11;
$texte = "Ce texte contient le nombre $a";

Le remplacement de $a par 11 aura bien lieu. Pour l'empêcher et pouvoir afficher un $ (ou un \ ou un "), on fait précéder ces caractères d'un antislash (\).

On peut également utiliser les séquences d'échappement, comme le \n déjà vu, ou \r (retour chariot), \t (tabulation), \l et \u (met la lettre suivante en minuscule ou majuscule resp.), \L ou \U (met tout ce qui suit en minuscule ou majuscule resp.), \E (annule les effets de \L ou \U) ...

Les chaînes peuvent également être encadrées d'apostrophes, ce qui se différencie des guillemets. Il n'y a alors pas de substitution pour les variables, et l'antislash n'a pas d'effet.

Opérateurs

Opérateurs numériques : ** (exposant), % (modulo), ...
Comparaisons numériques : <=> qui affecte -1, 0 ou 1 selon le résultat (inférieur, égal ou supérieur)
Comparaisons de chaînes : identique aux comparaisons numériques du Fortran (lt,gt,ge,ne, ...)
Sur les chaînes : . (concaténation), x (répétition), .= (concaténation et affectation)

Opérateur conditionnel (cf. C) :

$resultat = $var == 0 ? 14 : 7 ;

# Si $var==0 est vrai (resp. faux), on affecte 14 (resp. 7) à$resultat.


Opérateur ..  dans un contexte scalaire (voir ci-dessous pour un contexte "listes") :
Cet opérateur retourne ici une valeur booléenne, qui est vraie dès que l'argument de gauche est vrai et tant que l'argument de droite l'est aussi. Ca sera sans doute plus clair avec un exemple. Soit le fichier z suivant :
entete
debut
contenu
fin
signature
Et supposons que l'on veuille extraire le texte contenu entre les lignes debut et fin. Le script suivant conviendra :
#!/bin/perl
open(FICHIER,"z");
while(<FICHIER>) {
  if (m/^debut$/ .. m/^fin$/) {
     print $_;
  }
}
Si l'on veut en outre supprimer l'affichage de debut et fin, on peut modifier le script de la manière suivante :
#!/bin/perl
open(FICHIER,"z");
while(<FICHIER>) {
  if (my $num = m/^debut$/ .. m/^fin$/) {
     if ($num > 1 and $num !~ m/E/) {
         print $_;
     }
  }
}
 

Listes et tableaux

Une liste est constituée d'une séquence de variables scalaires encadrée de parenthèses, comme par exemple (1, 5.3, "hello", 2). On peut stocker ces listes dans des variables spécialement conçues, les variables-tableaux, dont le nom est précédé par @. On peut alors faire référence à n'importe quel élément du tableau comme s'il s'agissait d'une variable scalaire :
 

@tableau = (11, 12, 13) ;

 

$scalaire = $tableau [0] ;

# on affecte 11 a $scalaire

@sous_tab = @tableau[0,1] ;

# affecte 11 et 12 à @sous_tab

 

On notera que, comme en C, les indices des tableaux commencent à zéro. Si on tente d'accéder à un élément de tableau inexistant, Perl utilise à la place de celui-ci la chaîne nulle. On peut comme avec les variables scalaires lire et écrire des tableaux sur la sortie standard :
@tab = <STDIN> ;
print (@tab) ;

Il peut également être nécessaire de traiter ces entrées avec chop ...

Nota : print ($var[0]) va afficher la valeur du premier élément de la liste @var. Si l'on veut afficher en fait la valeur de $var suivie de "[0]", il faut indiquer que l'on sépare les deux parties : print (${var}[0]).

Utilisation de plages de listes

(1..5) est équivalent à (1, 2, 3, 4, 5).

(aaa..aad) est équivalent à (aaa, aab, aac, aad).

(3.3..5.6) est équivalent à (3.3, 4.3, 5.3, 5.6) : l'opérateur .. de plage de liste incrémente le premier élément d'une unité jusqu'au plus grand nombre qui demeure inférieur ou égal au dernier élément.

Copie d'un tableau

@final = @initial permet de copier la liste stockée dans @initial dans un nouveau tableau @final.

Affichage de tableaux
 

@tableau = (1, 2, 3);

print (@tableau, "\n");

# affiche 123

print ("@tableau\n");

# afficher 1 2 3


Affectation de tableaux à des scalaires

 

@tab = (1,2);

 

($v1,$v2) = @tab;

# affecte 1 à $v1 et 2 à $v2


Détermination de la longueur d'un tableau

 

$long = (12, 24, 36);

# affecte 3 à $long


Il est cependant préférable d'écrire :
$var = scalar(@tab) ;

En revanche, ($var) = @tab affecte, à cause des parenthèses, le premier élément de @tab à $var

Tri de tableaux


@tab2 = sort (@tab1) ;

# trie @tab1 et affecte le résultat du tri à @tab2


Le tri se fait dans l'ordre ASCII : ainsi 100 est considéré comme plus petit que 8.

Inversion d'un tableau


@tab1 = (12,13) ;

 

@tab2 = reverse (@tab1) ;

# affecte (13,12) à @tab2

 

Fusion d'une liste en une chaîne

 

$chaine = join (" ","petit","test");

# affecte "petit test" à $chaine

 

La séquence " " au début de join spécifie que l'espace est considéré comme séparateur. Le choix du séparateur est libre.

Scission d'une chaîne en une liste

 

@tab = split (/:/, $chaine) ;
 

# découpe $chaine en supprimant le caractère de séparation
# (ici, ":")


Suppression des doublons d'une liste

Il n'existe pas de fonction prédéfinie. On peut passer par une fonction telle que :
sub uniq{keys%{{map{$_,1}@_}}}
qui s'utilise comme suit :
@liste = uniq(@liste);

La première écriture de la fonction n'est évidemment pas très lisible. On peut l'éclaircir un peu de la manière suivante :

sub uniq {

 

 

my (@liste) = @_;

 

 

my @double = map {$_, 1} @liste;

# remplace chaque valeur par un couple (valeur, 1)

 

my %hash = (@double);

#  stocke cela dans une table de hashage

 

return keys %hash;

# extrait les clés (qui sont uniques par définition)

}