Chapitre 38 : PERL encore plus loin


Dernière mise à jour  27 mars 1997  Auteur Gilles Maire
Serveur  http://www.imaginet.fr/ime/perl3.htm Adresse Gilles.Maire@UNGI.com

38.1 - Les améliorations de forme

Introduction

Lors des premiers mois de publications d'UNGI, seule la version PERL 4.036 était stable et Windows 95 n'en était qu'à ses versions beta. Aujourd'hui, la version 5 du langage PERL permet de développer en toute confiance sur toutes les plates-formes.

 Citons la FAQ Win Perl [www.perl.hip.com/PerlFaq.htm] sous Windows 32 bits qui donne un grand nombre de conseils utiles. Nous allons nous engager dans ce chapitre à expliciter les ajoûts de la version 5 du langage PERL, le langage de référence pour qui veut :

Notons au passage, que le Web UNGI est géré par un grand nombre de programmes en PERL, au niveau des tables des matières, de la liste des fournisseurs, et que la version papier que l'on trouve en librairie, est générée par un programme PERL!

 Qui plus est, et autant que faire se peut, les exposés du chapitre introductif au langage PERL et les exercices donnés dans le chapitre exercices en Perl sont tous compilables en Perl5.

 Cependant, un certain nombre de points de divergences inévitables seront repris dans la suite de cet exposé (ils le seront quand les autres points auront été traités afin d'en faciliter la compréhention).

 

L'opérateur =>

En Perl 4 on pouvait initialiser un tableau associatif par l'une des syntaxes suivantes :

%tableau=("Gilles",23,"Pierre", 3312) ;

En perl5 ceci se fait aussi par la syntaxe suivante :

%tableau= (
'Gilles' => 23 ,
'Pierre' => 3312 ,
) ;

ce qui gagne en lisibilité.

Les expressions régulières

Les expressions régulières en PERL 5 comprennent celles définies dans le chapitre PERL 4 complétées par quelques extensions plus puissantes.

Les noms de variable étendus

Les variables $_, $., $& ne sont pas des plus faciles à retenir et compliquent inutilement la lisibilité du langage. A partir de la version 5 du langage toutes ces variables ont un équivalent en texte. Pour utiliser ces équivalents, il est nécessaire de placer en tête de fichier la directive :

use English ;

Suite à cette directive voici les correspondances des variables et leurs équivalents en texte plein.
 

Chaîne 
Raccourci 
Définition 
$PID $PROCESS_ID 
$$ 
numéro du process (UNIX) 
$FORMAT_PAGE_NUMBER 
$% 
numéro de la page du device de sortie 
$MATCH 
$& 
la chaîne de caractères correspondant à la dernière recherche 
$POSTMATCH 
$' 
valeur suivant le mot recherché dans la chaîne trouvée 
$REAL_GROUP-ID $GID 
$( 
gid réel du process (UNIX) 
$EFFECTIVE-GROUP_ID $EGID 
$) 
gid effectif du process (UNIX) 
$MULTILINE_MATCHING 
$* 
est à 1 si plusieurs lignes contiennent la chaîne recherchée 
$FORMAT_LINES_LEFT 
$- 
nombre de lignes imprimées sur la page de sortie 
$LAST_PAREN_MATCH 
$+ 
la dernière correspondance trouvée par une recherche 
$NR 
$. 
ligne courante 
$OUTPUT_FIELD_SEPARATOR $OFS 
$, 
séparateur de champs en sortie de la commande print utilisée avec des , en séparateur 
$SUBSCRIPT_SEPARATOR $ SUBSEP 
$; 
séparateur pour les tableaux multidimention 
$RS 
$/ 
séparateur de champs (nouvelle ligne par défaut) 
$OUTPUT_AUTOFLUSH 
$| 
de valeur non nulle force un flush après chaque écriture sur le canal de sortie (0 par défaut). 
$OUTPUT_RECORD_SEPARATOR $ORS 
$\ 
marque de fin de ligne en sortie de la commande print. 
$LIST_SEPARATOR 
$" 
séparateur de champs tableau en sortie de la commande print. 
$REAL_USER_ID $UID 
$< 
uid réel du process (UNIX) 
$FORMAT_LINES_PER_PAGE 
$= 
longueur de la page de sortie 
$FORMAT_LINE_BREAK_CHARACTERS 
$: 
jeu de caractère après lequel une chaîne peut être coupée pour remplir le champ suivant. 
$EFFECTIVE_USER_ID $SEUID 
$> 
uid effectif du process (UNIX) 
$CHILD_ERROR 
$? 
statut retourné par la dernière commande 
$ERRNO $OS_ERROR 
$! 
valeur du dernier code d'erreur (errno) 
$EVAL_ERROR 
$@ 
dernier message d'erreur provoqué par PERL 
$OFMT 
$# 
format de sortie pour les nombres imprimés (ne plus utiliser en PERL 5) 
NA 
$[ 
index du premier élément d'un tableau 
$PERL_VERSION 
$] 
version de PERL 
$FORMAT_TOP_NAME 
$^ 
nom du format courant d'en-tête de page 
$ACCUMULATOR 
$^A 
la valeur courante de l'accumulateur write() pour less ligne format() 
$DEBUGGING 
$^D 
état du flag de debug 
$SYSTEM_FD_MAX 
$^F 
nombre de descripteurs de fichier système 
$INPLACE_EDIT 
$^I 
valeur courante pour l'extension inplace-edit (voir option -i) 
$FORMAT_FORMFEED 
$^L 
envoie un Form Feed sur le canal de sortie 
$PERLDB 
$^P 
flag interne que le debugueur remet à zéro. 
$BASETIME 
$^T 
temps d'exécution de PERL 
$WARNING 
$^W 
valeur de la chaîne de Warning 
$EXECUTABLE_NAME 
$^X 
nom d'exécution du programme PERL 
$PREMATCH 
$` 
valeur précédant la chaîne trouvée lors de la précédente recherche 
$FORMAT_NAME 
$~ 
nom du canal de sortie 
$PREGRAM_NAME 
$0 
nom du fichier contenant le programme PERL en cours d'exécution 
NA 
$ARGV 
nom du fichier courant quand la lecture utilise <> 
NA 
@ARG 
contient les arguments passés au programme 
NA 
@INC 
contient les programmes PERL utilisés en librairie 
NA 
%INC 
contient les entrées de tous les fichiers inclus par la directive require 
NA 
@ENV 
contient les variables d'environnement 
NA 
@SIG 
contient la table de tous les signaux 

38.2 - Les extensions structurelles

Ces extensions sont en grande majorité celles qui donnent au langage PERL ses extensions de langage Objet.

Les paquetages

La notion de paquetage permet d'utiliser procédures et variables propres à un environnement appelé paquetage.

L'intérêt de tels paquetage est de fournir, un jeu de variable, de fonction et de structures de données spécialisés dans une tâche donnée.

 Chaque variable prédéfinie ainsi que les fonctions utilisées jadis dans la version PERL 4 sont issues aujourd'hui du paquetage main qui est celui utilisé par défaut.

 Une variable issue d'un paquetage est utilisée via la syntaxe suivante :

$nom du paquetage::variable

Si le nom du paquetage est omis, le paquetage à considérer est celui par défaut : le main. Un paquetage peut être inclus dans un autre paquetage et les utilisations de variable se feront par la syntaxe :

$paquetage1::$paquetage2::variable

Chacun des symboles utilisés dans un paquetage, est stocké dans un tableau associatif du nom du paquetage qu'on note avec les symboles ::, par exemple le tableau %main::, ou %:: est le tableau contenant tous les symboles du paquetage principal.

 Comme dans tous les langages objets, la notion de constructeur et de destructeur est présente en PERL 5; les deux mots clés permettant de mener à bien ces opérations sont BEGIN et END.

 Lorsqu'un paquetage doit être utilisé plusieurs fois, il est possible de le mettre en librairie, il se nomme alors Module. Un module est un paquetage qui a été inclus dans une librairie de même nom, sachant qu'un module est un fichier d'extension .pm et les noms des modules sont donnés en majuscules

Ainsi l'utilisation d'un module se fait par l'usage de la ligne

use module LISTE;

Cette syntaxe est équivalente à un

BEGIN { require "module.pm" ; import Module LIST ; }

le mot clé BEGIN permettant de construire et d'initialiser toutes les données du paquetage. Un certains nombre de modules sont inclus dans la distribution de PERL, il est recommandé d'aller regarder dans le répertoire lib de votre environnement PERL, les fichiers d'extension pm.

 Vous y trouverez :

Les pragma

Avant de regarder les paquetages disponibles de base, distinguons un groupe de modules appelés PRAGMA. Ces modules sont appelés PRAGMA car ils influencent la compilation des programmes. On dénombre parmi ceux-ci,

Les modules standards

Les modules étendus

Ces modules sont écrits en C et peuvent être chargés dynamiquement par l'interpréteur au moment où vous en avez besoin.

 Citons les pricipaux modules que l'on ne retrouve pas forcément dans l'environnement mais qu'il vous faudra aller chercher sur les CPAN :

Les structures étendues

PERL4, s'il introduisait les notions de tableaux indexés par des chaînes de caractères, ne permettait pas de construction plus complexe comme les tableaux de tableaux ou de fonctions, les références sur des variables et autres structures complexes qui se révèlent parfois indispensables.

 

Les constructions de références

Prenons la variable $valeur et assignons lui la variable $indice[0] premier élément du tableau de scalaire @indice. Ceci se faisait déjà par la syntaxe triviale :

@indice = (0,1,2,3) ;
$valeur = $indice[0] ;

En PERL 5 il est maintenant possible de modifier la déclaration précédente comme suit :

@indice = (0,1,2,3) ;
$valeur = \@indice ; 
print "$valeur->[1]" ;

On dit que $valeur est une référence sur le tableau @indice et on note $valeur->[x] un des éléments du tableau.

 

L'exemple précédent se généralise aux tableaux ou aux fonctions par des utilisations du style :

$reference1=\%ENV ;
$reference2=\&fonction;

Une autre construction valide peut être :

$autreexemple = {
'Gilles'=>'expert' ,
'Charles'=>'commercial',
'Luc'=>'formateur',
'Nathalie'=>'commerciale',
} ; 
print "$autreexemple->{'Luc'}\n";

Faire une fonction qui retourne une référence sur un tableau nécessite de mettre un caractère + ou return devant l'instruction de bloc :

sub retournereference { + {@_} } ;
sub retournereference { return {@_} } ;

Ainsi la référence suivante est elle même valide :

$reference = sub { print "ok\n" ; } ;
&$reference() ;  # affiche ok

Il est encore possible d'utiliser des références de références comme le montre les exemples suivant :

$ligne="ok"; 
print $ligne ; #affiche ok
$ligne=\"ok";
print $$ligne  ; affiche ok
$ligne=\\"ok";
print $$$ligne  ; affiche ok

Mais le lecteur débutant prendra soin de bien utiliser les parenthèses s'il ne sait pas que les deux expressions sont identiques

$$refref{"Gilles"} = "expert" ;
${$refref}{"Gilles"} ="expert" ;

mais que la suivante n'est pas valide :

${$refref{"Gilles"}} ="expert" ; # c'est ${$refref->{"Gille"}}="expert" ; qui l'est

Ce tour d'horizon se complique par une notion qui est fondamentale : prenons un tableau a deux dimensions :

$pixel->[0]->[0] = 1;
$pixel->[0]->[1] = 2;
$pixel->[1]->[0] = 3;
$pixel->[1]->[1] = 4;
print "$pixel->[1]->[1]\n" ; # vaut 4 ....

Ceci est un peu compliqué à écrire pour un tableau a deux dimensions !

Il existe un seul cas où vous pouvez supprimer les -> : ENTRE deux accolades ou crochets. Ainsi le tableau précédent pouvait s'écrire

$pixel->[0][0] = 1;
$pixel->[0][1] = 2;
$pixel->[1][0] = 3;
$pixel->[1][1] = 4;
print "$pixel->[1][1]\n" ; # vaut 4 ....

C'est une subtilité non négligeable, qui permet d'utiliser les tableaux multidimentionnels comme en C, à la différence que l'allocation est ici dynamique et aucune réservation de mémoire n'est nécessaire en Perl puisque vous pouvez ajouter, à tout moment, des éléments supplémentaires dans un tableau. Prenons en guise résumé les autres exemples suivants :

$Maire{age} = 34 ;
$Maire{sexe} = masculin ; 
$nom=Maire ;
$ref=nom ;
print "$$ref\n"; # affiche Maire
print "$$ref->{age}\n" ; # affiche 34 
$nom=Nicolas;
$$ref->{age} = 46 ;
$$ref->{sexe} = masculin ;
print "$Maire{age} $Nicolas{age}\n"; # affiche 34 46

Ceci vous montre la puissance du langage et la simplicité avec laquelle il permet de traiter les données. Nous finirons notre tour d'horizon par l'exemple de tableau complexe suivant :

$reftableau = [1,2,
['Gilles','Luc','Nathalie','Charles']
]
print "$reftableau->[0]" ; # affiche 1 
print "$reftableau->[2][1]" ; # affiche Luc

38.3 - PERL 5 langage orienté objet

Paquetages, allocations dynamiques, il ne manque plus que la manipulations des objets pour comprendre que le langage PERL est le langage résolument moderne et incontournable pour celui qui veut mettre en oeuvre des CGI.

 Au passage ceci est renforcé par le fait qu'un programme écrit en PERL fonctionne de la même façon sur une machine UNIX sur un PC sous Windows 3, Windows 95 ou Windows NT voire sur un Macintosh.

 Vu la facilité avec laquelle il permet de manipuler les documents texte en HTML, et la rapidité du langage, on comprend qu'il reste encore l'outil de référence des développeurs de serveurs Web.

 Là où un développeur C++ confirmé doit coder 400 lignes pour analyser un texte, PERL fournit la syntaxe en une ligne, alliant efficacité et élégance!

38.4 - La librairie CGI.pm

Nous avons parlé du module CGI.pm au début de notre introduction au langage PERL et aux CGI.
Maintenant que nous avons étudié les principales lignes du langage, il est judicieux d'analyser ce module qui est le pivot de l'écriture de CGI.

 La documentation fournie avec la paquetage est assez bien faite, et nous nous contenterons d'en tirer les principales lignes.

La déclaration d'utilisation peut être faite par l'une des méthodes suivantes :

Dans le premier cas, l'utilisation d'une instantiation de l'objet de type CGI devra être explicite, c'est à dire qu'après une déclaration du type :

$html=new CGI;

la variable $html devra être expicitée dans le premier cas et pas dans le deuxième. Ainsi dans lchacun des  cas on écrira :

Il est à noter que l'objet  CGI peut être utilisé  de différentes façons:

L'utilisation de la valeur standard signifie que le HTML niveau 2  et les CGI seront accessibles par l'objer CGI.
Mais d'autres valeurs peuvent être données :
 

cgi  param(), path_info(), cookie(), request_method()... 
form  start_form() textfield() .. 
html2  les balises suivants la norme HTML 2 : p(), br(), head(), body(), start_html(), end_html().. 
html3  les balises de la norme HTML 3.2 
netscape  les balises de Netscape 
html  html3, html2 et Netscape 
standard  tout sauf Netscape et HTML 3 
all  toutes les méthodes 

Les méthodes de lecture

Nous allons donner toutes les méthodes de l'objet CGI qui servent à lire des informations envoyées par le navigateur par le tableau suivant :
 

méthodes  Se rapporte à  Type  Définition  Exemple 
param  CGI  @tableau  retourne un tableau contenant tous les objets 
Lorsque le paramètre est multi valué chaque champs est renvoyé dans un tableau, sinon dans une valeur. 
@noms=$html->param @valeur=$html->param('nom1') $valeur=$html->param('nom1')
keywords  CGI  @tableau  retourne un tableau contenant tous les objets désignés par la balsie ISINDEX  @motscles=$html->keywords 
save  CGI  action  sauve le contenu de la requête dans le fichier ouvert en écriture par le handler donné en argument.  $html->save(FICHIER) 
accept  CGI  @tableau  retourne la liste des types MIME que le navigateur accepte si aucun agrument n'est donné 
retourne 0 si un type MIME est passé et que le navigateur ne le reconnait pas 
retourne 1 si un type MIME est passé et que le navigateur le reconnait 
if (html->accept('text/html')) 

Les méthodes d'écriture

Le module CGI.pm permet la manipulation de tous les objets connus en HTML :


Haut Haut Suivant Sommaire Recherche Fenêtre Glossaire Nouveau Bientôt Courrier Souscription Aide Copyright