Dernière mise à jour | 27 mars 1997 | Auteur | Gilles Maire |
Serveur | http://www.imaginet.fr/ime/perl3.htm | Adresse | Gilles.Maire@UNGI.com |
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).
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 en PERL 5 comprennent celles définies dans le chapitre PERL 4 complétées par quelques extensions plus puissantes.
split (/\b(?:a|b|c)\b/)
est équivalent à
split (/\b(a|b|c)\b/)
/w+(?=\t)/
permet de trouver tous les mots suivis d'une tabulation sans inclure cette tabulation dans les mots trouvés.
/titi(?!toto)/
permet de trouver tous les mots titi non suivis de toto. On comprend que cette expression ne doit pas démarrer l'expression régulière.
/titi|(?i)toto/
permet de trouver les occurrences de titi mais aussi de toto, de Toto de TOTO etc .
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.
|
|
|
|
---|---|---|---|
|
|
numéro du process (UNIX) | |
|
|
numéro de la page du device de sortie | |
|
|
la chaîne de caractères correspondant à la dernière recherche | |
|
|
valeur suivant le mot recherché dans la chaîne trouvée | |
|
|
gid réel du process (UNIX) | |
|
|
gid effectif du process (UNIX) | |
|
|
est à 1 si plusieurs lignes contiennent la chaîne recherchée | |
|
|
nombre de lignes imprimées sur la page de sortie | |
|
|
la dernière correspondance trouvée par une recherche | |
|
|
ligne courante | |
|
|
séparateur de champs en sortie de la commande print utilisée avec des , en séparateur | |
|
|
séparateur pour les tableaux multidimention | |
|
|
séparateur de champs (nouvelle ligne par défaut) | |
|
|
de valeur non nulle force un flush après chaque écriture sur le canal de sortie (0 par défaut). | |
|
|
marque de fin de ligne en sortie de la commande print. | |
|
|
séparateur de champs tableau en sortie de la commande print. | |
|
|
uid réel du process (UNIX) | |
|
|
longueur de la page de sortie | |
|
|
jeu de caractère après lequel une chaîne peut être coupée pour remplir le champ suivant. | |
|
|
uid effectif du process (UNIX) | |
|
|
statut retourné par la dernière commande | |
|
|
valeur du dernier code d'erreur (errno) | |
|
|
dernier message d'erreur provoqué par PERL | |
|
|
format de sortie pour les nombres imprimés (ne plus utiliser en PERL 5) | |
|
|
index du premier élément d'un tableau | |
|
|
version de PERL | |
|
|
nom du format courant d'en-tête de page | |
|
|
la valeur courante de l'accumulateur write() pour less ligne format() | |
|
|
état du flag de debug | |
|
|
nombre de descripteurs de fichier système | |
|
|
valeur courante pour l'extension inplace-edit (voir option -i) | |
|
|
envoie un Form Feed sur le canal de sortie | |
|
|
flag interne que le debugueur remet à zéro. | |
|
|
temps d'exécution de PERL | |
|
|
valeur de la chaîne de Warning | |
|
|
nom d'exécution du programme PERL | |
|
|
valeur précédant la chaîne trouvée lors de la précédente recherche | |
|
|
nom du canal de sortie | |
|
|
nom du fichier contenant le programme PERL en cours d'exécution | |
|
|
nom du fichier courant quand la lecture utilise <> | |
|
|
contient les arguments passés au programme | |
|
|
contient les programmes PERL utilisés en librairie | |
|
|
contient les entrées de tous les fichiers inclus par la directive require | |
|
|
contient les variables d'environnement | |
|
|
contient la table de tous les signaux |
Ces extensions sont en grande majorité celles qui donnent au langage PERL ses extensions de langage Objet.
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 :
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,
Exemple :
use strict 'refs' ; $toto=4 ; $titi=toto ; print $$titi ; # provoque une erreur de compilation alors que # sans la première ligne le chiffre 4 s'afficherait
Cet exemple restreint la puissance du langage Perl, puisque l'une des astuces préférées des développeurs est de faire des tableaux de procédures, et de lancer ces appels par une syntaxe du genre :
$fonction="$nomdeprocedure[4]" ; &$fonction;
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 :
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.
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
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!
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:
$html = new CGI ( {'nom1'=>'valeur1','nom2'=>'valeur2'})
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 |
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')) |
Le module CGI.pm permet la manipulation de tous les objets connus en HTML :