Découvrir Perl

Stéphane TOUGARD

1  Ce qu'est PERL

Je me souviens de mes quatorze ans et de mon Thomson TO7. Je faisais mes premiers pas en Basic : j'avais rédigé un petit programme qui servait à écrire un courrier, un autre qui affichait une pendule. Sur un MO5, je rentrais les formules et renvoyais les résultats vers les faibles fonctions graphiques de l'époque pour afficher des dessins.

Plus tard, sur un MS Quick Basic, je jouais encore à programmer ces inutiles << utilitaires >> : un tableau indiquant toutes les heures de chaque capitale, un générateur de nombres aléatoires, un pendu, une interface de programmation pour une machine-outil,...

Puis vint Windows et sa pauvreté naturelle en langages simples. Je découvrais DBase, Paradox, ne voulus même pas entendre parler des pseudo basics pour Windows, essayai sans succès le Pascal et quelques autres de ses collègues, puissants, plus puissants que n'importe quel Basic, mais compliqués, inutilement compliqués.

Avec Linux et les script Bash, je retrouvais la joie grâce à de petits programmes simples, rapidement écrits, assez puissants pour s'amuser sans s'investir et dont la syntaxe et la logique peu éloignées du Basic me donnaient l'impression de ne pas avoir appris un langage pour rien.

Enfin, un beau matin, sur les conseils d'un ami, j'essayais Perl. Sans le savoir, j'avais rencontré le langage idéal, rapide, simple, à la syntaxe souple et légère. Puissant, infiniment plus puissant que n'importe quel Basic : des bibliothèques partout, des fonctions toutes plus complexes ; et pourtant, dix lignes de code donnaient déjà un résultat et encourageaient à continuer un code si bien commencé.

Car Perl s'avère bien plus qu'un simple langage de script. Il peut tout faire : de la grosse application, comme du script de tri ; associé à Tk, il va jusqu'à gérer les fenêtres et les menus déroulants ; il permet en cinq minutes de réaliser le petit script incroyable dont la fonction manque tant aux utilitaires habituels ; il peut simplifier autant un traitement par lots que la gestion d'une base de données de plusieurs giga-octets.

2  Mon premier programme en Perl

Cherchons tout d'abord où se trouve le binaire Perl sur notre disque.

~$ find / -name perl 2>/dev/null
/usr/bin/perl
~$

Bien entendu, si Perl se trouve dans /usr/bin sur mon système, il n'en est pas forcément de même sur le vôtre, il peut loger dans /usr/local/bin par exemple, ou dans un autre sous-répertoire.

Au même titre que n'importe quel shell, Perl consiste en un langage interprété - ce qui signifie qu'un script Perl ne se compile pas.

À l'instar de sh (par exemple), il est nécessaire de spécifier dès le départ que notre script est écrit en Perl. Pour ce faire, nous ajouterons à la première ligne du programme #!/usr/bin/perl (ou le chemin absolu vers l'interpréteur Perl de votre système).

Notre premier programme Perl sera très simple. Il va faire intervenir une saisie au clavier et afficher à l'écran ce qui a été saisi :

#!/usr/bin/perl
$saisie = <STDIN>;
print("$saisie");

Sauvegardons notre script dans le fichier essai. Rendons-le exécutable avec la commande chmod et exécutons-le.

Notre script essai va attendre que vous saisissiez quelque chose au clavier ; puis, une fois que vous aurez appuyé sur la touche Entrée, il affichera une seconde fois ce que vous avez tapé. Étudions donc ce très simple script, ligne après ligne :

Lorsque nous saisissons une entrée via <STDIN> , nous la validons avec la touche Entrée. Cette dernière envoie un caractère \n à la variable que Perl nous rend, en revenant à la ligne après avoir affiché $saisie .

Souvent, ce << retour-chariot >> en fin de ligne se révèle gênant. Nous verrons plus loin comment l'enlever au moyen de la commande chop .

La syntaxe de Perl est aussi simple que cela. Chaque instruction se termine par un point-virgule et l'utilisation des << espaces, guillemets, parenthèses,... >> apparaît très libre (à tel point que, selon le programmeur, des lignes semblables de code peuvent ne pas se ressembler du tout).

3  Les entrées-sorties

Comme avec tout système Unix, Perl gère les entrées-sorties. Nous avons vu, dans la première section, l'entrée et la sortie standard ; il suffira de créer un pointeur sur un fichier pour les rediriger sur des fichiers.

Commençons par sauvegarder notre saisie dans un fichier après l'avoir affichée à l'écran.

#!/usr/bin/perl
print("Quel texte aller vous rentrer :");
$texte = <STDIN>;
chop($texte);
open(OUT,">essai");
print("Vous avez tapé $texte !\n");
print OUT"Sur le disque $texte est sauvegardé\n";
close(OUT);

Voyez vous-même dans le fichier essai que le contenu correspond bien à ce que vous avez tapé.

Qu'avons-nous fait ?

Si nous souhaitons ajouter une information dans un fichier, il faudra le préciser au pointeur de la même façon que dans un script shell, en utilisant le signe >> plutôt que le signe >.

Lire dans un fichier se passe d'une manière un peu similaire. Supposons maintenant que nous voulions lire le contenu de notre fichier essai.

#!/usr/bin/perl
open(IN,"<essai");
while(<$_>){
print("$_");
}
close(IN);

Étudions ce que notre script effectue :

Nous constatons l'utilisation de la variable $_ . Cette variable, nommons-la variable par défaut. Perl fait toujours appel à la variable par défaut lorsqu'il informe le programme sur le contenu de l'entrée standard.

4  Les boucles et les condition

Nous avons vu, dans le premier chapitre, les bases des entrées-sorties. Peut-être l'avez-vous remarqué, au détour d'un exemple, un while s'est glissé.

Pour bien comprendre à quoi sert while , étudions d'abord son petit frère if .

if a pour ordre de réaliser une tâche si une condition est remplie et de ne pas réaliser cette tâche (mais peut-être une autre) si cette condition n'est pas remplie. if est accompagné par else et elsif . Le premier réalisera une tâche si la condition n'est pas remplie ; le second réalisera une tâche si la première condition n'est pas remplie mais que la seconde l'est. Vous suivez ? Non ? Bon, un exemple sera plus parlant. Le programme qui suit vous dit si vous êtes majeur ou non.

#!/usr/bin/perl
print("Quel est votre \^age :");
$age = <STDIN>;
chop($age);
if($age < 18){
	print("Vous \^etes mineur\n");
}
elsif($age > 17){
	print("Vous \^etes majeur\n");
}
else{
	print("Soyez sérieux, entrez votre \^age, pas n'importe quoi\n");
}

Une boucle possède à peu près la même fonction que la condition, à ceci près qu'elle doit réaliser une action tant qu'une condition se vérifie.

Les opérateurs :

Opérateur sur texte sur nombres
Égal à eq ==
Différent de ne !=
Inférieur à ls <
Supérieur à gt >
Inférieur ou égal le <=
Supérieur ou égal ge >=

5  Les sous-programmes

Dans la conception d'un programme, il arrive qu'une même tâche nécessite d'être répétée plusieurs fois avec des arguments différents. Une série de copier-coller se met alors en place. Ce qui entraî ne un grossissement du code alarmant, mangeur de ressources,... Bref, du code pas propre.

Heureusement, Perl offre la possibilité de définir à l'avance des sous-programmes auxquels il est loisible de redonner des arguments afin qu'ils réagissent d'une manière ou d'une autre.

#!/usr/bin/perl
$tot = "votre nom";
$nom = &input($tot);
print("$tot est $nom");
sub input{
	print("Quel est $_[0] :");
	$var = <STDIN>;
	chop($var);
	return $var;
}

Nous voyons tout de suite ici l'avantage d'une telle formule. En fait, le sous-programme &input retourne une valeur saisie au clavier en affichant une question qui dépend d'un argument donné. Une fois ce sous-programme écrit, il devient simple d'y faire appel pour remplir n'importe quelle variable par la simple commande :

$variable = &input($argument);
 

Ce qui apparait tout de même plus simple et plus rapide que de ré-écrire la suite de fonction en entier à chaque fois.

6  Les accès au système de fichiers

Perl ne sait pas tout faire. Il offre une fonction bien pratique pour faire appel à un programme extérieur : la commande system() . Celle-ci transmet directement au shell par défaut la commande mise entre parenthèses.

#!/usr/bin/perl
system("emacs");

va avoir pour fonction de lancer le programme emacs.

Perl offre cependant la possibilité de réaliser un certain nombre d'opérations sur les fichiers et répertoires du disque sans passer par un shell quelconque. Quel est l'avantage, me direz-vous, de passer par une commande Perl là où l'on pourrait tout bonnement faire un appel system ? La réponse est simple : la Portabilité. Aujourd'hui, vous réalisez un programme Perl sous Unix, mais qui vous dit qu'un utilisateur de Windows NT ne travaillera pas un jour avec votre script ? Que, vous-même, vous ne changerez pas de plateforme ? Et puis, plus simplement, n'est-il pas plus intéressant de créer des programmes propres, juste pour le plaisir ?

Les opérations que propose Perl sont les plus courantes offertes par un shell :

Commande Perl fonction
rename() renomme ou déplace un fichier
unlink() efface un fichier
symlink(,) crée un lien symbolique (ln -s)
chdir() change de répertoire
mkdir() crée un nouveau répertoire
rmdir() efface un répertoire

Pour un équivalent de la commande ls , il va nous falloir écrire un petit sous-programme :

sub ls{
	while(<*>){
		print("$_\n");
	}
}

Voilà. Il suffira ensuite d'appeller le sous-programme &ls pour que s'affiche à l'écran le contenu du répertoire courant.

7  Recherche d'une occurence dans un fichier

Perl offre un grand nombre de fonctions pour traiter les chaînes de caractères, trop pour que nous puissions en faire le tour ici. Nous allons cependant en découvrir quelques-unes.

La fonction s a son importance : elle recherche une occurence et la remplace. Mais son rôle va plus loin. Elle retourne en valeur le nombre de remplacements qu'elle a effectués. Voyons tout de suite un exemple :

#!/usr/bin/perl
print("Quel mot voulez-vous rechercher :");
$cherche = <STDIN>;
chop($cherche);
$ligne="0";
$sum="0";
$cond="0";
while(<>){
$cond=$sum;
$ligne +=1;
$sum += (s/\b$cherche\b/$cherche/g);
if($cond != $sum){
print("Ligne $ligne ==> ");
print("$sum\n");
};
};
print("----------------------------------------------------\n");
print("Votre fichier contient $sum fois le mot \'$cherche\'\n");

Ce petit script, en définitive, vous indique à quelle ligne il trouve une occurence donnée dans un texte et combien de fois il la trouve. Enfin, il vous informe sur le nombre total d'occurences dans le fichier traité.

Ce n'est certainement pas la seule manière d'aboutir à ce résultat - Perl abonde en fonctions de ce genre - mais cette solution se montre utile à connaître et à exploiter.

8  Partager une variable en tableau

Nous allons étudier maintenant une autre fonction de Perl : split() .

Nous avons vu comment se servir avec profit des variables. Or, il existe sous Perl une autre manière de les ranger : les tableaux.

Une variable commence par $ , un tableau commence par @ et se découpe en variable.

Illustrons notre propos par l'exemple d'un petit script Perl qui transforme un tableau retourné par Postgres95 en un tableau lisible par LATEX  :

#!/usr/bin/perl
print("\\documentclass{article}\n");
print("\\usepackage{a4}\n");
print("\\usepackage[frenchb]{babel}\n");
print("\\selectlanguage{francais}\n");
print("\\usepackage[latin1]{inputenc}\n");
print("\\usepackage[T1]{fontenc}\n");
print("\\frenchspacing\n");
print("\\begin{document}\n");
print("\\begin{tabular}{\|l\|l\|r\|r\|l\|l\|}\n");
print("\\hline\n");
print("Date \& Sujet \& Crédit \& Débit \& Numéro \& Rapproché \\\\ \n");
print("\\hline\n");
open(EP, "<rap-banque");
$ctotal = "0";
$dtotal = "0";
while(<EP>){
chop;
@_ = split(/\|/, $_);
printf("$_[0] \& $_[1] \& %.2f \& %.2f \& $_[4] \& $_[5]  \\\\ \n", $_[2], $_[3]);
$ctotal = $ctotal + $_[2];
$dtotal = $dtotal + $_[3];
};
print("\\hline\n");
printf(" - \& TOTAL \& %.2f  \& %.2f \& - \& - \\\\ \n", $ctotal, $dtotal);
print("\\hline\n");
print("\\end{tabular}\n");
print("\\end{document}\n");

Remarquez à la ligne 19 l'utilisation de split() pour éclater une variable en un tableau dont nous allons récupérer chaque élément à la ligne 20.

La commande split() prend deux options entre ses parenthèses ; celles-ci (à l'habitude de Perl) sont séparées par une virgule. La première est mise entre / et contient le champ séparateur ; la seconde s'avère tout simplement la variable à éclater en tableau.

On peut récupérer les valeurs du tableau en utilisant les variables qui le composent. Ainsi, @_ contient les variables $_[0], $_[1],\dots (Notez que le premier champ du tableau est numéroté 0 et non 1).

9  Trouver des informations

Cette documentation ne se veut qu'un très bref aperçu de Perl. S'il vous a donné envie de découvrir ce langage, alors je considérerai avoir atteint mon objectif en l'écrivant.

Il existe de nombreux endroits où trouver de la documentation à propos de Perl : d'abord sur Usenet (fr.comp.lang.perl), également dans la presse (la revue Dream propose de nombreux articles traitant des fonctions de Perl).

Pour qui dispose de notions d'anglais, la source la plus complète se trouve sur votre propre ordinateur. La commande perldoc vous donne une quantité non négligeable d'informations sur les commandes Perl. Au prompt, tapez perldoc perldoc pour en savoir davantage.

Il existe enfin les livres des éditions O'Reilly : le Lama book, pour débuter. Ce livre vous apportera une base solide pour comprendre Perl. Si vous vous en sentez l'envie, passez au Camel Book, qui approfondit le sujet et explique des fonctions très pointues de Perl. Ces ouvrages sont disponibles en français.


File translated from TEX by TTH, version 1.98.
On 19 Jan 1999, 03:24.