\input{gabaritlatin1perl.tex}
\input{macroslatin1.tex}

%\advance\textwidth by -3 cm
%\advance\voffset by -2 cm
\advance\textheight by 1 cm
\newcommand{\notemg}[1]{\marginpar{\scriptsize{#1}}}
% \hspace{-1.5cm}\textbf{Remarques}


\title{Programmation éditoriale\\
II. Introduction à Perl}

\author{Éric Guichard\footnote{Maître de conférences à l'ENSSIB, 
responsable de l'équipe \RST \ de l'École normale supérieure.}}

\begin{document}

\maketitle


Ce document est une initiation à Perl pour \emph{non-informaticiens}. Il ne se confond donc pas avec les  multiples documentations,  aides, tutoriels et conseils, en ligne ou imprimés (\cite{LPerl, castro}, etc.). J'ai donc ici l'unique intention de détailler des choses très simples et de proposer quelques approches, méthodes et  astuces  pour les personnes désireuses de se familiariser dans la gaité et l'humour à la programmation. Le prochain tutoriel proposera une introduction à la programmation de pages web dynamiques\footnote{Le précédent tutoriel consistait en une initiation (sans douleur) à Unix/Linux.}.


\medskip
\textbf{Note}: la table des matières est à la fin du document.

%\section{Quelques références}
%Deux  ouvrages particulièrement clairs: .
\bibliography{../../Conferences-articles/biblio2005}
\bibliographystyle{/sw/share/texmf-dist/bibtex/bst/base/smfplain}

Une \textbf{excellente introduction}  dans Linux Magazine (incontournable): \\
\url{http://articles.mongueurs.net/magazines/dossiers/01}

Ou, du même auteur: 
\url{http://sylvain.lhullier.org/publications/intro_perl/index.html}

Sinon, toujours en français mais plus détaillé:\\
\url{http://perl.enstimac.fr}

Et partout ailleurs sur le web. Par exemple: \\
\url{http://www.perl.com/pub/q/documentation}

%\newpage

\section{Confort minimal}
\subsection{Prolégomène}
Je conseille fortement de lire et relire cette documentation et celle de  \emph{Linux Magazine}. De même pour \emph{Learning Perl}, si vous l'avez sous la main. N'hésitez-pas non plus à lancer (et modifier) les petits programmes que je propose. En informatique, c'est en faisant des erreurs et en multipliant les essais qu'on apprend.

\medskip

Nous allons utiliser Perl dans une situation simple, qui combine écriture du programme dans un fichier et son lancement dans une fenêtre \emph{terminal}\notemg{Pour plus d'informations sur le \emph{terminal}, cf. \url{http://barthes.enssib.fr/cours/Linux/Linux-1.pdf}. 
	Je rappelle que sur un Mac, le terminal se trouve dans 
	(Applications -> Utilitaires -> Terminal.app) et que 
	tous les logiciels Linux y fonctionnent (souvent) très bien, 
	quand ils ne sont pas déjà pré-installés.}. 
Autrement dit, vous avez besoin d'avoir deux \emph{fenêtres} ouvertes et deux seulement. Par la suite, je note \texttt{pgm1.pl} le fichier dans lequel est écrit le programme.

Voici le contenu de ce fichier intitulé \texttt{pgm1.pl}:
\begin{verbatim} print ("Bonjour \n"); \end{verbatim}

En l'occurrence, dans une fenêtre \emph{terminal}, nous saisirons la commande\\
\texttt{perl pgm1.pl} \\suivie d'une pression sur la touche \emph{passage à la ligne} (aussi appelée \emph{retour-chariot}) pour transmettre cette commande à la machine et le résultat s'affichera dans la même  fenêtre:\\
\texttt{Bonjour} 

\subsection{Déjà des problèmes?}
Et si ça ne fonctionne pas?
Voici les  trois principales causes d'insuccès:

\begin{enumerate}
\item Perl n'est pas installé: on vous répond alors \texttt{perl: Command not found}. Parfois, c'est moins grave qu'il n'y paraît:  Perl est installé, mais son chemin d'accès n'est pas mémorisé par le système. Cela arrive fréquemment sur Windows. En ce cas, il faut préciser où est Perl. Exemple de solution (sans garantie): au lieu de \texttt{perl pgm1.pl}, saisissez \\
\texttt{C:$\backslash$Program Files$\backslash$Perl$\backslash$perl.exe pgm1.pl}

\emph{Note optimiste}: Perl est pré-installé sur Mac (OS X) et Linux.

\item Le fichier \texttt{pgm1.pl} n'est pas à l'endroit prévu: dans le \emph{terminal}, à coups de \texttt{cd} (\emph{change directory}), positionnez-vous dans le dossier contenant ce fichier \texttt{pgm1.pl} (cf. ici encore ma documentation \href{{http://barthes.enssib.fr/cours/Linux/Linux-1.pdf}}{Linux}). Pour vérifier votre localisation,  saisissez la commande:\\
\texttt{ls pgm1.pl}\\
Si vous obtenez la réponse \\
\texttt{ pgm1.pl} \\
(avec éventuellement des choses bizarres devant), c'est tout bon. \\
Sinon, on vous répondra: \\
\texttt{ls: pgm1.pl: No such file or directory}.

\item Votre système d'exploitation a rajouté une extension à votre nom de fichier. Windows s'amuse souvent à faire ce genre de choses. Par exemple vous croyez avoir nommé votre fichier \texttt{pgm1.pl}, et il s'appelle  en fait \texttt{pgm1.pl.txt}, ou pire \texttt{pgm1.pl.rtf}, voire \texttt{pgm1.pl.doc}!\\
D'où le conseil suivant.

\end{enumerate}

\subsection{Maîtriser l'écriture avec les \emph{éditeurs}}
Demandez au système d'exploitaiton de ne pas ajouter d'extensions incongrues à vos noms de fichiers, sinon de les afficher en clair. Comprenez aussi que les formats de fichier type Word  \emph{ne sont pas les bons}, et trouvez sur le web des \textbf{logiciels qui vous permettent d'écrire en mode \emph{texte}}.

On appelle de tels logiciels des \emph{éditeurs}, et il y en a des centaines. En plus, ils sont souvent gratuits. Sur Windows, \emph{TeXnicCenter} fonctionne très bien (\url{http://www.texniccenter.org/}). Sur Mac ou Linux, \emph{nedit, Aquamacs, emacs, kwrite, Dashcode, Bbedit} (ce dernier payant sur Mac) sont aussi d'excellents  éditeurs. Un éditeur se repère au fait qu'il {\color{red}colorie} souvent les commandes importantes du programme que vous écrivez\marginpar{\scriptsize{Ex.: \\{\color{blue}print} {\color{red}"Bonjour"}; \\ \$a = 1;}}.
Plus précisément, il propose une aide visuelle à la syntaxe qui dépend du fichier que vous rédigez (un programme Perl, un texte en \LaTeX, etc.). 

\subsection{Convention}
Dans tout ce qui suit, la succession des lignes écrites avec une police à espacement fixe (\texttt{comme cela}) peuvent être copiées dans le fichier \texttt{pgm1.pl} et vous pouvez voir leur effet\notemg{N'oubliez pas de sauvegarder le fichier \texttt{pgm1.pl} après chaque modification; sinon elles ne seront pas prises en compte.} en saisissant la commande \texttt{perl pgm1.pl} dans une fenêtre terminal. Suivant les cas, le résultat s'affichera à l'écran, ou dans un fichier.

\section{Les fichiers}

\subsection{Écrire dans un fichier}
L'écriture d'un résultat dans un fichier est simple: on ouvre un fichier, on lui donne un nom simple pour mieux le <<tenir>> (le \emph{filehandle}, de préférence en majuscules), qui est un alias et on y inscrit ce que l'on désire. 

Exemple\marginpar{\scriptsize{Le symbole > est important! }}:\\
\texttt{
open (F, ">resu.txt");  \\
print F "Bonjour $\backslash$n";\\
close (F);
}

Ceci crée un fichier  \emph{resu.txt} qui contient le mot \emph{Bonjour} suivi d'un espace et d'un retour-chariot: le \textbf{$\backslash$n} signifie \emph{ajoutez un symbole de fin de ligne à la suite de ce qui précède}.

La mention \texttt{close (F);} n'est pas indispensable, mais est vivement conseillée et on s'efforcera de \emph{fermer} un fichier ouvert dès qu'on n'en a plus l'usage.

\subsection{Lecture ligne à ligne: Perl \emph{et} Unix!}
Vous l'avez compris, ce qui distingue une ligne de la suivante est ce  \texttt{$\backslash$n}: symbole cabalistique  tout à fait compréhensible mais quasiment invisible. 

En informatique, ce \emph{passage explicite à la ligne} est de toute première importance. C'est lui qui permet de repérer la fin de la ligne\footnote{Je néglige le fait que certains programmes (de l'ancien temps) ne puissent accepter des lignes de grande longueur: Perl accepte des lignes de longueur quasi-infinie.}. 

Nous devons comprendre qu'ici, la littératie de l'imprimé et nos pratiques de lecture déteignent sur la façon dont sera \emph{lu} un fichier électronique: il sera parcouru ligne après ligne et de gauche à droite.

Mais le marqueur de fin de ligne pose aussi quelques soucis: déjà, il y a de fortes chances pour qu'il soit difficile à \emph{attraper}\footnote{D'autant qu'il varie selon les systèmes d'exploitation: LF pour Linux/unix, CR pour Mac, CR/LF (les deux) pour Windows.}; ensuite, il \emph{dénature} le contenu intuitif de la ligne (n'oublions pas que les ordinateurs ont une intelligence nulle).

Par exemple, supposons qu'une ligne soit composée des trois prénoms \\
\texttt{Marie Jessica Aurélie} \\
(séparés comme indiqué par des espaces), et que nous voulions y repérer les prénoms se terminant par «ie».
Nous ne trouverons pas \emph{Aurélie}, car la fin d'\emph{Aurélie} n'est pas \emph{ie} mais \emph{ie$\backslash$n}. 

\emph{La} solution pour cela est la commande \texttt{chomp}, qui supprime le dernier caractère de la ligne \emph{à condition} qu'il soit un séparateur de ligne\marginpar{\scriptsize{Elle est donc plus sélective que  la commande \texttt{chop}.}}.

\subsection{Application: lire un fichier}
Un exemple valant mieux qu'un long discours...\notemg{Le chemin d'accès \texttt{/home/etc.} est bien entendu fantaisiste: modifiez-le à votre convenance (cf. la commande \texttt{pwd}).}
\begin{verbatimtab}[5]
open (F,"/home/chezmoi/dossier_test/monfichier");
while (<F>)
	{
	chomp;
	print $_;
	#toutes les lignes seront affichées à l'écran 
	#sans ce fameux retour-chariot
	#Faire d'autres choses...
	}
close (F);	
\end{verbatimtab}

\hspace{-1.5cm}\textbf{Remarques}:
\begin{enumerate}
\item le \texttt{\$\_} est une variable interne à Perl, qui se confond ici avec la ligne courante. 
Perl facilitant l'écriture implicite, nous  aurions pu écrire aussi: 
\begin{verbatimtab}[5]
print; #au lieu de print $_;
\end{verbatimtab}
ce qui aurait produit la même chose.

\item Vous l'avez compris, le dièse (\texttt{\#}) sert de commentaire dans un programme Perl: tout ce qui suit jusqu'à la fin de la ligne n'est pas pris en compte.
\end{enumerate}


\subsection{Lire et écrire}
Il est aisé (et fréquent) de combiner la lecture d'un fichier et l'écriture de résultats dans un autre fichier.
Gardons en tête le fait que pour  traiter efficacement et sans surprise  un fichier, il faut \emph{supprimer} les caractères de fin de ligne. En revanche, pour que le fichier résultat soit un tant soit peu lisible par les humains que nous sommes, il faudra les \emph{rajouter}.

Voici un exemple. Pour qu'il ne soit pas trivial, je précise que parmi les variables prédéfinies par Perl (comme \texttt{\$\_}), existe la variable \texttt{\$.} qui donne le numéro de la ligne lue.
Avec un \emph{éditeur}, constituez un fichier simple de quelques lignes. Appelez-le \emph{monfichier.txt};
Nous allons le recopier dans un autre fichier, en précisant à chaque fois le numéro de la ligne:
\begin{verbatimtab}[5]
open (F,"/home/chezmoi/dossier_test/monfichier.txt"};
open (RESU,">/home/chezmoi/dossier_test/resultat.txt"};
while (<F>)
	{
	chomp;
	print RESU $_;
	#imprime dans RESU la ligne SANS le retour-chariot
	print RESU " se trouve en ligne $. \n";
	}
close (F);	
close (RESU);
\end{verbatimtab}

Si, par exemple, la cinquième ligne du fichier \emph{monfichier.txt} est:\\
\emph{La nuit est bien noire ce soir}

La cinquième ligne du fichier \emph{resultat.txt} sera:\\
\emph{La nuit est bien noire ce soir se trouve en ligne 5}

Et derrière le chiffre <<5>>, nous trouverons un espace, et un passage à la ligne.

\medskip
\hspace{-1.5cm}\textbf{Remarques}
\begin{enumerate}
\item La commande \texttt{print} sans alias de nom de fichier derrière, affiche donc ce que l'on désire \emph{sur l'écran du terminal}; suivie d'un alias\notemg{L'alias est ce fameux \emph{filehandle}.} (ex.: \texttt{print RESU}), elle inscrit ce que l'on désire  \emph{dans le fichier qui a cet alias}.

\item Les guillemets doubles permettent de combiner du texte \emph{et} des variables (telles que \texttt{\$.}, \texttt{\$\_}, etc.); seront écrits le texte \emph{et} la valeur de la variable (et non pas les symboles qui la composent). Ceci n'aurait pas été le cas si nous avions utilisé des guillemets simples (apostrophes\notemg{Les  guillemets simples <<\texttt{'}>> sont appelés \emph{quotes} en anglais. Les guillemets doubles <<\texttt{"}>>, \emph{double quotes.}}): alors, les variables n'auraient pas été \emph{interpolées}.
\end{enumerate}

\section{Les variables}
Il y a dans Perl trois grands  types de variables: les variables scalaires (\emph{scalar}), les listes (\emph{array}) et les tableaux indexés (\emph{hash}).

Il est conseillé de préciser le statut relatif des variables, mais ce n'est pas obligatoire pour les programmes simples: une variable peut être (définie comme) \emph{locale} (\texttt{my}) ou \emph{globale} (\texttt{our}\notemg{Une variable sans précision est par défaut considérée comme globale.}). 
\subsection{Variables scalaires}
Une variable dite \emph{scalaire} est la plus petite \emph{boîte} imaginable. Il n'est pas nécessaire de préciser la \emph{destinée} de la variable (si elle contiendra du texte, un nombre, une commande, etc.). C'est d'ailleurs une des  forces de Perl. 

Une variable scalaire se repère au signe \texttt{\$} qui précède son intitulé:
\begin{verbatimtab}[5]
my $couleur="vert";
my $a = 3.5;
my $phrase ="le petit chat est rouge";
\end{verbatimtab}

Il est aisé de réaliser des opérations sur les variables. 
Exemples (simples):
\begin{verbatimtab}[5]
my $phrase ="le petit chat est $couleur";
my $b= 2*$a; #$b vaut évidemment 7
$phrase = $phrase x 2; 
#$phrase contient alors deux fois le texte initial;
\end{verbatimtab}

\hspace{-1.5cm}\textbf{Remarque}

Au début, évitez de modifier les variables prédéfinies de Perl (comme \texttt{\$\_}, \texttt{\$.}, etc. Vous risqueriez de drôles de surprises. 

\subsection{Listes}
\subsubsection{Approche élémentaire}
Une liste est une succession (une... liste) de variables. On peut l'assimiler à un vecteur.
Une liste  se repère au signe \texttt{@} qui précède son intitulé:
\begin{verbatimtab}[5]
my @liste_a_moi=(2, huit, chat, rouge, $phrase); 
\end{verbatimtab}

Cette liste est composée de 4 éléments, dont le premier a pour indice (numéro)\marginpar{\scriptsize{En informatique, pour des raisons tenant aux mathématiques et à la logique, le premier élément a souvent pour numéro de \emph{dossard}  0.}} 0. Ici, le dernier a donc l'indice (je dis aussi \emph{dossard} ou \emph{index}) 3. Pour récupérer le second élément (\emph{huit}), c'est tout simple, si on se souvient du fait qu'une liste est composée de variables scalaires: le <<nom>> de cet élément commencera par \$, il aura celui de la liste, et il sera repéré par son index.
\begin{verbatimtab}[5]
my @liste=(2, huit, chat, rouge, $phrase); 
my $second= $liste[1]; #$second vaut huit
print $second;
#ou
print $liste[1],"\n";
#pour récupérer $phrase:
my $nouveau= $liste[4];
\end{verbatimtab}

Une liste peut être assez implicite:
\begin{verbatimtab}[5]
my @liste_a_moi=(1..10); #contient 1, 2, 3,... 10
@liste_a_moi=(a..z,2, huit, chat);
\end{verbatimtab}

Le premier élément d'une liste ayant pour numéro 0, le dernier aura pour numéro la longueur de la liste -1. Perl a une variable spéciale pour le référencer: \texttt{\$\#liste};

On peut réaliser une multitude de traitements sur une liste. Je renvoie aux documentations, et ne présente ici que l'instruction la plus fréquente: \textbf{foreach}.

\subsubsection{Deux exemples avec \emph{foreach}}
\begin{enumerate}

\item Cas le plus simple:

\begin{verbatimtab}[5]
my @liste_a_moi=(2, huit, chat, rouge, $phrase); 
foreach my $nimportequoi (@liste_a_moi)
	{
	#la variable $nimportequoi est automatiquement
	#créée et va prendre successivement
	#toutes les valeurs des élements de la liste.
	print $nimportequoi,"\n"; 
	#on affiche à l'écran ces éléments;
	}
\end{verbatimtab}

\item Si on veut attraper les éléments pairs de la liste\notemg{Dans cet exemple, on utilise le signe \texttt{\%}, qui signifie <<modulo>>.}.

\begin{verbatimtab}[5]
foreach my $dossard (0..$#liste_a_moi)
	{
	print $liste_a_moi[$dossard],"\n" if $dossard % 2 ==1; 
	#Un élément de la liste sera donc imprimé si le reste 
	#de la division par deux de son numéro (index)
	#vaut 1 (rappel: le second élément a pour numéro 1).
	}
\end{verbatimtab}
\end{enumerate}

\hspace{-1.5cm}\textbf{Remarque} 

Si on est exigeant en matière syntaxique, on enchâsse les éléments textuels de la liste en des apostrophes (\emph{quotes}):
\notemg{Ou si les éléments de la liste l'imposent (fragments de phrase, etc.).}
\begin{verbatimtab}[5]
@liste_a_moi=(a..z,'2', 'le chat');
\end{verbatimtab}

\subsubsection{Liens entre listes et variables}
\begin{enumerate}
\item Construire une liste à partir d'une variable: la commande \texttt{split}.

On choisit les termes qui vont servir de séparateurs et on obtient une liste.
Dans l'exemple qui suit, les séparateurs sont les espaces, cités entre les deux signes \texttt{/}:

\begin{verbatimtab}[5]
$phrase="voici quelques mots";
@liste_a_moi=split(/ /,$phrase); 
#@liste_a_moi est alors ('voici','quelques','mots');
#On le vérifie ainsi:
foreach my $cequimepasseparlatete (@liste_a_moi)
	{
	print $cequimepasseparlatete,"\n";
	}
\end{verbatimtab}

Que se passe-t-il si le séparateur est vide? Tous les termes de la liste sont coupés par... rien, et on obtient tous les caractères de \texttt{\$phrase}. Cet exemple, \emph{a priori} stupide, est \textbf{fort utile pour repérer les erreurs dans les OCR} (reconnaissance optique des caractères), où les confusions entre les <<1>> (un) et les <<l>> (lettre L), entre les <<O>> et les <<0>> sont fréquentes.

\begin{verbatimtab}[5]
@liste=split(//,"voici quelques mots"); 
foreach my $u (@liste)
	{
	print "début",$u,"fin\n";
	}
\end{verbatimtab}


\item Construire une variable à partir d'une liste: la commande \texttt{join}.

Le principe est le même: on \emph{joint} les termes de la liste par un séparateur.
\begin{verbatimtab}[5]
@liste=('voici','quelques','mots'); 
$liant=" TT ";
$a= join($liant,@liste);
print $a,"\n";
#Plus rapide:
print join(" TT ",@liste);
\end{verbatimtab}

\end{enumerate}

\subsection{Les tableaux indexés ou \emph{hash(es)}}
On peut  voir un tableau indexé comme une double liste, ou comme une liste de listes. Cela peut être un vrai tableau (une matrice), ou un objet plus complexe (tri-dimensionnel, etc.).
Cependant, le \emph{hash}\marginpar{\scriptsize{Je préfère le terme anglais \emph{hash} car certaines documentations françaises traduisent \emph{list} par <<tableau>>. Par suite, on ne sait jamais si un tableau est indexé ou pas...}} renvoie à du bon sens.
Aussi, avant  d'en détailler la syntaxe et l'usage, je vais commencer par un petit détour.

\subsubsection{Décrire un tableau}

Par exemple, comment repérer simplement le tableau  suivant?
\begin{verbatimtab}[5]
0	1	Bonjour
2	3	4
1	0	$phrase
\end{verbatimtab}
%$
Il suffit de décrire les valeurs du tableau en fonction de leurs positions: par exemple, en ligne 1 et colonne 1, j'ai \texttt{0}. En ligne 2 et colonne 3, j'ai  \texttt{4}. 

On a alors envie d'écrire:\\
\texttt{\$tableau\{ligne1col1\}= 0;}\\
...\\
\texttt{\$tableau\{ligne2col3\}= 4;}\\
etc.

En d'autres termes, pour chaque \emph{clé} (\emph{lignexcoly}), on définit une \emph{valeur}. Nous remarquons là que n'importe quel tableau, aussi complexe soit-il, peut être décrit ainsi, et donc être \emph{réduit} à un tableau à deux colonnes: la première pour les clés, la seconde pour leurs valeurs.
Et la matrice  précédente peut être ainsi décrite:
%\begin{verbatimtab}[5]
%clé			valeur
%ligne1col1	0	
%ligne1col2	1
%...
%ligne2col3	4
%...
%ligne3col3	$phrase
%\end{verbatimtab}

\begin{tabular}[h]{|l|l|} \hline
\emph{clé}		&	\emph{valeur} \\ \hline
ligne1col1	& 0	\\ \hline
ligne1col2	& 1\\ \hline
... &\\ \hline
ligne2col3	&4\\ \hline
... &\\ \hline
ligne3col3	& \$phrase \\ \hline
\end{tabular}
\medskip

C'est exactement le sens d'un \emph{hash}: une succession de clés et de valeurs.

\subsubsection{Définir un \emph{hash}}

Un \emph{hash} est repéré par le symbole \%, et il y a mille et une manières de le définir: 
\begin{enumerate}

\item comme nous venons de le faire: en écrivant \\
\texttt{\$tableau\{ligne1col1\}= 0;\\
\#etc.}

Ceci a défini le \emph{hash} intitulé  \texttt{\%tableau}\marginpar{\scriptsize{Il aurait été sage d'écrire auparavant dans le programme: \\
\texttt{my \%tableau;}}}.

\item Un peu comme une liste: \\
\texttt{\%tableau =(ligne1col1, 0, ligne1col2, 1); \#etc.}

Bien sûr, on a avantage à l'écrire plus clairement:\\
\texttt{\%tableau =('ligne1col1', '0', \\
'ligne1col2','1')};

\item Et la façon la plus courante depuis la version 5 de Perl:\\
\texttt{\%tableau =(ligne1col1 =>0, ligne1col2 => 1)};
\end{enumerate}

Un \emph{hash} est donc  une double liste: liste de \emph{clés}, et listes de \emph{valeurs} associées.
C'est un peu comme une fonction mathématique\marginpar{\scriptsize{Mais l'analogie s'arrête là: les objets ressemblant le plus à des fonctions mathé\-matiques sont les (sous-)routines, définies par le mot-clé \texttt{sub}.}}: à chaque clé est associée une valeur et une seule. Bien sûr,  plusieurs clés peuvent avoir la même valeur.

De ce fait, il est aisé de repérer les deux listes qui composent le \emph{hash}: elles s'appellent tout simplement \emph{keys} et \emph{values}.
Exemples:
\begin{verbatimtab}[5]
@liste_de_mes_cles= keys %tableau;
@ma_seconde_colonne= values %tableau;
foreach my $bazar (keys %tableau)
	{
	print $bazar, " ", $tableau{$bazar},"\n";
	}
\end{verbatimtab}[5]
	
\hspace{-1.5cm}\textbf{Remarque} 

Un tableau indexé est un instrument très puissant. On peut par exemple fabriquer des tableaux de tableaux. \textbf{Cependant, un \emph{hash} est toujours désordonné}: les valeurs sont certes bien attachées à leurs clés, mais les listes des unes comme des autres  sont toujours renvoyées \emph{dans un ordre peu compréhensible}. Il existe des solutions, en demandant à trier (par ordre alphabétique, numérique, ou construit par ses soins) ces clés ou valeurs.
Exemple:

\begin{verbatimtab}[5]
foreach my $bazar (sort keys %tableau)
	{
	print $bazar, " ", $tableau{$bazar},"\n";
	}
\end{verbatimtab}[5]

\hspace{-1.5cm}\textbf{Question}: que se passe-t-il si j'écris?\\
\texttt{\%tableau = @liste;}\\
ou l'inverse?\\
\texttt{@liste= \%tableau ;}

\hspace{-1.5cm}\textbf{Réponse}: ce que le bon sens nous indique...
Ce qui est agréable avec Perl, c'est qu'on  peut oser un peu tout ce qu'on veut.
Quitte à multiplier les essais, et à consulter les documentations.

\subsubsection{Construction d'un \emph{hash} au fil de l'eau}
Ce point précise comment définir  implicitement un \emph{hash}. Supposons par exemple que nous voulions repérer tous les caractères d'une phrase et seulement eux (pensons ici encore à l'OCR). Il suffit de faire comme suit:
\notemg{On aurait pu faire plus simple avec une liste (commande \texttt{push}), mais l'idée est ici de montrer comment définir des \emph{ensembles}.}


\begin{verbatimtab}[5]
$phrase="Quoi? Vous voulez la réponse à 2+2?";
foreach my $bazar (split(//,$phrase)) # je vais vite...
	{
	$tableau{$bazar}=1;
	}
\end{verbatimtab}[5]

Par ce moyen, on a donc créé un \emph{hash} nommé \texttt{\%tableau} qui contient comme clés les caractères de la phrase (lettres, espace et ponctuation), et comme valeurs le nombre \emph{1}.
Auparavant, il n'existait pas. Et maintenant, ses clés et valeurs sont exactement ce que nous avons voulu qu'elles soient.

Pour voir le contenu de ce tableau, il nous suffit d'écrire:
\begin{verbatimtab}[5]
foreach $u (keys %tableau)
	{
	print "le caractère $u apparaît dans $phrase \n";
	}
\end{verbatimtab}[5]

ou, plus simplement:
\begin{verbatimtab}[5]
print join("TTT",keys %tableau);
\end{verbatimtab}[5]

Comme je le disais, cette liste est bien désordonnée. Vous voulez un tri?
\begin{verbatimtab}[5]
print join("TTT",sort keys %tableau);
\end{verbatimtab}[5]

\hspace{-1.5cm}\textbf{Remarques}
\begin{enumerate}
\item Le <<Q>> apparaît avant le <<a>>, le <<à>> après le <<z>>. Effectivement, ce tri simple (\emph{sort}) dépend du classement informatique (d'abord les nombres, ensuite les Majuscules, après les minuscules, puis les caractères accentués). Il est possible de produire des tris plus subtils.

\item J'ai été un peu vite en besogne, mais c'est pour que vous preniez conscience de tous les implicites rendus possibles par Perl. Voici ce que donnerait le même programme détaillé:
\begin{verbatimtab}[5]
$phrase="Quoi? Vous voulez la réponse à 2+2?";
@liste= split(//,$phrase);
foreach my $bazar (@liste) 
	{
	$tableau{$bazar}=1;
	}
foreach $u (sort keys %tableau)
	{
	print "le caractère $u apparaît dans la ligne \n";
	}
	
\end{verbatimtab}[5]
\end{enumerate}
On peut évidemment améliorer un tel tableau, par exemple en comptant le nombre d'apparitions des caractères. Comment faire? Ici encore, il est inutile de \emph{prédéfinir} le spectre du tableau. Nous allons le construire au fur et à mesure:

\begin{verbatimtab}[5]
$tableau{$bazar}=$tableau{$bazar} + 1;
#ou mieux:
$tableau{$bazar}+=1;
#j'ajoute 1 
#ou encore
$tableau{$bazar}++;
\end{verbatimtab}[5]

Synthèse\notemg{Le \texttt{my \%tableau} sert à réinitialiser le tableau, si jamais vous l'avez déjà utilisé dans un exemple précédent. j'aurais pu écrire: \texttt{undef \%tableau};}
\begin{verbatimtab}[5]
my %tableau;
$phrase="Quoi? Vous voulez la réponse à 2+2?";
@liste= split(//,$phrase);
foreach my $bazar (@liste) 
	{
	$tableau{$bazar}++;
	}
foreach $u (sort keys %tableau)
	{
	print "le caractère $u apparaît $tableau{$u} fois \n";
	}	
\end{verbatimtab}[5]

\subsection{Vive l'autonomie}
À partir de maintenant, vous avez de solides compétences: vous pouvez vous plonger dans les  documentations et dictionnaires relatifs à Perl, explorer les limites d'interpolation des variables, découvrir seul(e)  les instructions de contrôle (\texttt{if, while, until...} vous connaissez déjà \texttt{foreach}), tester par vous-même ce qui est syntaxiquement possible et ce que produisent ces syntaxes.

\section{Motifs} \label{motif}
J'appelle motif (textuel) toute forme graphique (donc textuelle) composée de tout et n'importe quoi: lettres, nombres, signes de ponctuation, etc. La traduction anglaise de motif est \emph{pattern}. Un motif peut servir à décrire les mots commençant par une majuscule ou finissant par \emph{aît}, des url (\texttt{<a href="...">}, des nombres (comme 2,5 ou -16.87), etc.

\subsection{Substitution}
L'opération la plus simple consiste à réaliser une sorte de recherche/rempla\-cement. Elle s'applique à des variables et sa syntaxe est la suivante (\texttt{s} comme \emph{substitute}):

\texttt{s/recherche/remplace/;} 

En pratique, on précise la variable sur laquelle opérer la transformation, suivie de l'opérateur \texttt{=\~} (un signe <<égal>> suivi d'un signe <<tilde>>).\notemg{Le <<tilde>> s'obtient avec les touches <<Alt-n>> (Mac) ou <<Alt\_Gr-2>> (Linux, alors suivies d'un espace pour visualiser ce \emph{flottant}).}
Cet opérateur (le \emph{bind}) est essentiel. 
Exemple:

\begin{verbatimtab}[5]
my $a="Bonjour tout le monde";
$a=~s/o/w/;
print $a,"\n";
#réponse: Bwnjour tout le monde
\end{verbatimtab}[5]

La subtitution accepte divers paramètres. Le plus fréquent est le \texttt{g}: il garantit que le remplacement va s'opérer partout où c'est possible.

\begin{verbatimtab}[5]
$a="Bonjour tout le monde";
$a=~s/o/w/g;
print $a,"\n";
#réponse: Bwnjwur twut le mwnde
\end{verbatimtab}[5]

On a envie de faire plus sophistiqué:
\begin{verbatimtab}[5]
$a=~s/jou/soi/g;
#donnera: Bonsoir tout le monde
\end{verbatimtab}[5]

Voire de tenter un \emph{joker}. C'est possible, et en Perl (comme souvent en informatique), l'invocation de n'importe groupe de caractères (vide inclus) se fait via la succession des deux caractères \texttt{.*}: Le \texttt{.} signifie \emph{n'importe quel caractère} (sauf le passage à la ligne) et le \texttt{*} signifie \emph{apparaissant 0, 1 ou plusieurs fois}.

Un exemple valant mieux que de longs discours:
\begin{verbatimtab}[5]
$a="Bonjour tout le monde";
$a=~s/j.*r/soir/g;
#ce qui commence par j et finit par r sera remplacé par soir
print $a,"\n";
#réponse: Bonsoir tout le monde
\end{verbatimtab}[5]


\subsection{Repérage d'un motif}
On peut aussi repérer un tel motif.  Cela se fait avec le \texttt{m} (comme \emph{match}, correspondance), et la syntaxe est la même. Souvent, un repérage est associé à une condition:
\begin{verbatimtab}[5]
$a="Bonjour tout le monde";
if ($a=~m/jour/)
	{
	#si $a contient "jour"
	print "il doit fait jour car j'ai entendu Bonjour\n";
	}
else
	{
	#sinon
	print "il doit faire nuit\n";
	}
\end{verbatimtab}[5]

La plupart du temps, on oublie le \texttt{m}:
\begin{verbatimtab}[5]
$a="Bonjour tout le monde";
if ($a=~/j.*r/)
	{
	print "il doit fait jour\n";
	}
else
	{
	print "il doit faire nuit\n";
	}
\end{verbatimtab}[5]

\hspace{-1.5cm}\textbf{Remarque}

Bien sûr, il faut être prudent: on peut avoir des surprises car notre \emph{joker} est gourmand par nature. Exemple:
\begin{verbatimtab}[5]
$a="Bonjour tout le monde";
$a=~s/j.*u/soi/g;
print $a,"\n";
#réponse: Bonsoit le monde
\end{verbatimtab}[5]

\subsection{Variables prédéfinies associées}
Quand un tel repérage est fait, avec les commandes \texttt{s} ou \texttt{m}, Perl garde en mémoire le motif sélectionné\notemg{L'apostrophe inverse \texttt{\`} n'est pas toujours facile à saisir au clavier... Dans tous les cas, faites la suivre d'un espace, elle risquera moins de disparaître.} (variable \texttt{\$\&}), ce qui le précède (\texttt{\$\`}) et ce qui le suit (\texttt{\$\'}).
L'usage de ces trois variables est déconseillé par certains experts car elles ralentissent l'exécution du programme. Mais je les trouve fort utiles pour les débutants.

Exemple\notemg{~\\
J'en profite ici pour montrer la souplesse du \texttt{print} et rappeler l'interpolation de variables entre les guillemets.}:
\begin{verbatimtab}[5]
$a="Bonjour tout le monde";
$a=~s/o/w/;
print "début: $`
motif trouvé: $& 
fin: $' \n";
\end{verbatimtab}[5]

Le résultat affiché sera:
\begin{verbatimtab}[5]
début: B
motif trouvé: o 
fin: njour tout le monde 
\end{verbatimtab}[5]

On comprend que Perl s'arrête ici au \emph{premier} <<o>> rencontré. Ce serait l'inverse avec le programme suivant:
\begin{verbatimtab}[5]
$a="Bonjour tout le monde";
$a=~s/o/w/g;
print "début: $` motif trouvé: $&  
fin: $' \n";
#Résultat affiché ci-dessous:
début: Bonjour tout le m motif trouvé: o 
fin: nde 
\end{verbatimtab}[5]

\section{Les expressions régulières}
Elles généralisent ce que j'ai introduit au point \ref{motif}. Les expressions régulières\notemg{En français orthodoxe, une expression régulière est appelée <<expression rationnelle>>. Ses diminutifs anglais sont \emph{regex} ou \emph{regexp}.} constituent la force de Perl, au point que beaucoup d'autres \emph{langages de programmation} les ont intégrées (ex.: Php). 

Elles ouvrent la porte de la programmation aux experts en sciences humaines. Ici encore, je renvoie aux documentations, bien plus détaillées que ce cours, et me limiterai à quelques exemples.

\subsection{Philosophie}
Il y a deux façon de considérer les expressions régulières. On peut penser que c'est une horreur sans nom, et qu'il faut des années pour se familiariser avec. L'autre approche est plus empirique: on commence par se familiariser avec les plus simples, et on développe une série de méthodes personnelles. N'hésitez pas à  fragmenter votre travail en utilisant plusieurs expressions régulières simples et \emph{lisibles} plutôt que chercher la superbe expression régulière qui pourrait produire en une ligne ce que les autres font en dix.

\subsection{Quelques formes courantes d'expressions régulières}
Je présente ici un  nombre fort réduit de syntaxes d'expressions régulières et de raccourcis des précédentes, en confondant volontairement les deux. Ici encore, la documentation en ligne ou imprimée est exhaustive. 
\begin{itemize}
\item \texttt{$\backslash$w} \hspace{1cm} un mot: ce qui contient des lettres (non accentuées dans le cas général), des chiffres, et le symbole \texttt{\_} \notemg{Voir le point \ref{accent} pour en savoir plus sur la gestion des accents.}

\item \texttt{$\backslash$W} \hspace{1cm} tout ce qui n'est pas un mot (souvent la ponctuation, et parfois les lettres accentuées...)

\item \texttt{$\backslash$d} \hspace{1cm} un chiffre (entre 0 et 9); équivalent à  \texttt{[0--9]}

\item \texttt{\^} \hspace{1cm} désigne le début de la cible. Impose souvent que l'expression régulière qui le suit apparaisse dès le début de la ligne

\item \texttt{[des\_caractères]} \hspace{1cm} repère l'un des caractères cités entre le \texttt{[} et le \texttt{]}. Ce type d'expression, comme le suivant, est \emph{souvent suivi d'un} \texttt{*} ou  d'un \texttt{+} (pour signifier: apparaissant 0 ou plusieurs fois, une ou plusieurs fois)

\item \texttt{[\^}\texttt{des\_caractères]} \hspace{1cm} exclut tous les caractères cités entre le \texttt{[} et le \texttt{]}

\end{itemize}

\subsection{Exemples simples}
\subsubsection{Usage direct}
\begin{verbatimtab}[5]
$a="Bonjour tout le monde; il est 17h30";
if ($a =~/\d+h\d+/)
	{
	#si $heure contient des chiffres, un "h" et d'autres chiffres
	$heure =$&;
	print $heure,"\n";
	#affiche 17h30
	}
if ($a =~/^B.*r/)
	{
	#si $a commence par un B et contient un r
	print "la phrase commence par $& \n";
	#affiche: la phrase commence par Bonjour
	}
\end{verbatimtab}


\hspace{-1.5cm}\textbf{Attention! Piège possible}
\texttt{\$\&} renvoie le dernier motif non vide. Ce n'est pas toujours ce que vous espérez. Exemple:
\begin{verbatimtab}[5]
$a="Bonjour tout le monde; il est 17h30";
$heure =$& if ($a =~/\d+h\d+/);
#$heure vaut: 17h30
if ($a =~/^C.*r/)
	{
	#si $a commence par un C et contient un r
	print "la phrase commence par $& \n";
	#affiche: la phrase commence par 17h30
	#(l'ancienne valeur de $& ...)
	}
\end{verbatimtab}
	
	
\subsubsection{Avec la commande \texttt{split}}
Nous allons rechercher les <<mots>> de la phrase \emph{Bonjour! dit-il à tous. Il est 17h30}. Il nous faut donc utiliser les espaces et la ponctuation comme séparateurs et les intégrer dans une expression régulière. Voir les remarques ci-dessous.

\begin{verbatimtab}[5]
my $a="Bonjour! dit-il; il est 17h30...";
my @listemots=split(/[ !;\.-]+/,$a);
print join ("TT", @listemots);
#affiche: BonjourTTditTTilTTilTTestTT17h30
\end{verbatimtab}[5]

\hspace{-1.5cm}\textbf{Remarques}
\begin{enumerate}
\item Certains caractères pouvant entrer dans la définition d'expressions régulières doivent être \emph{protégés}: on les précède d'un <<$\backslash$>>. C'est le cas du <<\texttt{.}>>, qui devient <<\texttt{$\backslash$.}>> dans l'expression régulière.
Les autres caractères à protéger sont: \texttt{+ ? * \^} \texttt{ \$ ( ) [ ] | et $\backslash$}.

\item Comme le tiret intervient aussi dans la formulation d'une expression régulière, il faut lui aussi le protéger, sinon le mettre à la fin de l'expression, comme dans l'exemple précédent.
\end{enumerate}

\subsection{Affectation directe}
On peut mettre en mémoire ce qui est repéré sans passer par la variable \texttt{\$\&}, si on le met entre parenthèses. La syntaxe est un peu plus délicate. 
Exemples: 
\begin{verbatimtab}[5]
$a="Bonjour tout le monde; il est 17h30";
(my $b)= $a =~/(^B.*r)/;
#ce qui suit est mieux:
($b)= ($a =~/(^B.*r)/);
print $b,"\n";
#affiche dans les deux cas: Bonjour
\end{verbatimtab}[5]

\hspace{-1.5cm}\textbf{Attention}: la parenthèse autour de \texttt{\$b} est essentielle! Voyons ce qui se passe si on l'oublie:
\begin{verbatimtab}[5]
my $b= $a =~/(^B.*r)/;
print $b,"\n";
#affiche 1 (témoin de la correspondance: valeur "vrai")
$b= $a =~/(^C.*r)/;
print $b,"\n";
#N'AFFICHE RIEN!  (pas de correspondance: valeur "faux")
\end{verbatimtab}[5]

\begin{verbatimtab}[5]
(my $heure)= ( $a =~/(\d+h\d+)/);
print $heure,"\n";
#affiche 17h30
\end{verbatimtab}

On peut aussi être plus direct, en intégrant toutes les occurrences repérées par \emph{les} motifs entre parenthèses dans une liste. Certes, l'expression régulière devient complexe; mais une solution de simplification sera proposée au point \ref{simpleregex}.
\begin{verbatimtab}[5]
($b, $heure)= ( $a =~/(^B.*r).*(\d+h\d+)/);
print $b," ",$heure,"\n";
#affiche Bonjour 7h30, ce qui est normal car le chiffre 1
#a été absorbé par le .*
\end{verbatimtab}

\hspace{-1.5cm}\textbf{Solution:}
\begin{verbatimtab}[5]
($b, $heure)= ( $a =~/(^B.*r)[^\d]*(\d+h\d+)/);
#[^\d]* signifie n'importe quoi, tant que ce n'est pas un chiffre
print $b," il est ",$heure,"\n";
#affiche Bonjour il est 17h30
\end{verbatimtab}

Si vous désirez en savoir plus, vous pouvez aussi regarder la documentation sur les variables prédéfinies \texttt{\$1}, \texttt{\$2}... \texttt{\$9}.

\subsection{Intégrer une expression régulière dans une variable} \label{simpleregex}
Comme tout cela devient compliqué, je propose une solution personnelle pour manipuler plus aisément les  expressions régulières en les glissant dans une variable. Placée aux bons endroits, cette dernière sera interprétée comme nous le désirons.

\subsubsection{Méthode}
Commençons par un exemple simple, où l'expression régulière correspond à  une seule variable. Nous devinons qu'il nous faudra \emph{protéger} les caractères spéciaux avec un $\backslash$:

\begin{verbatimtab}[5]
$a="Bonjour tout le monde; il est 17h30";
my $expr1= "\^B\.*r";
print $& if $a=~/$expr1/;
#renvoie Bonjour
my $expr2= "\\d+h\\d+";
print $& if $a=~/$expr2/;
#renvoie 17h30
\end{verbatimtab}

C'est déjà agréable de pouvoir réduire une expression régulière rarement lisible dans une variable au nom explicite. Cela nous donne alors l'idée  de décomposer en morceaux notre précédente expression régulière. Je la rappelle ci-après:
\begin{verbatimtab}[5]
(^B.*r)[^\d]*(\d+h\d+)
\end{verbatimtab}

Nous voulons prendre en considération:
\begin{enumerate}
\item ce qui commence par un B et finit par un r, à mettre entre parenthèses pour l'intégrer dans une variable;

\item ce qui, ensuite, ne contient pas de chiffre et dont on se moque (parenthèses inutiles);

\item enfin, ce qui correspond à l'heure (qui entrera dans une variable).
\end{enumerate}

La fortune souriant aux audacieux, tentons ce qui suit\notemg{Pour mémo, les noms des variables à retenir (expressions régulières entourées de parenthèses) se terminent,  par un \emph{m}.}:

\begin{verbatimtab}[5]
my $regexpdebutm="(^B\.*r)";
my $nondecimal="[\^\\d]*";
my $regexpheurem="(\\d+h\\d+)";
#concaténons les 3 expressions régulières
# Cela se fait avec le point .
my $regexp_pas_belle= $regexpdebutm.$nondecimal.$regexpheurem;
my ($b, $heure)= ($a=~/$regexp_pas_belle/);
print $b," ",$heure,"\n";
#affiche Bonjour 17h30
\end{verbatimtab}[5]

Avouons-le, cette solution n'est pas idéale\notemg{Vous avez remarqué qu'ici, il n'était pas indispensable de protéger les parenthèses.}, mais elle  est fort utile quand on se perd avec les protections, surtout quand nous proposons à l'utilisateur de choisir lui-même ses séparateurs.

\subsubsection{Application à une liste complexe}

Voyons un dernier exemple avec \texttt{split}, qui rend plus lisible la liste des séparateurs à utiliser:

\begin{verbatimtab}[5]
my $separateurs="[ #début de la série des séparateurs de mots
, #je n'écris qu'un signe de ponctuation par ligne
; #pour garantir la lisibilité
\. 
\(
\)
\?
!
 #ici l'espace
]+"; #fin de ma série des séparateurs de mots

$separateurs=~s/\#.*\n//g; #supprime les commentaires
$separateurs=~s/\n//g; #supprime les passages à la ligne
print $separateurs,"\n";
#affiche [ , ; . ()?! ]+
#certes, il y a des espaces en trop, mais ce n'est pas un souci

my $a="Bonjour à tous! il est 17h30 (enfin, je crois).";
my @listemots=split (/$separateurs/,$a);
foreach my $mot (@listemots)
	{
	print $mot," ";
	}
print "\n";	
\end{verbatimtab}

Ce programme affiche à l'écran:
\begin{verbatimtab}[5]
Bonjour à tous il est 17h30 enfin je crois
\end{verbatimtab}

\section{En savoir plus}

Cette partie sert de conclusion: si vous avez lu jusqu'ici cette documentation, et que vous en avez testé tous les exemples, vous pouvez sans souci vous plonger dans celles que je vous ai conseillées au début de cet article.
\subsection{Bibliothèques et modules}
Il existe des milliers de bibliothèques (ou modules)  dans le moteur même de Perl, et vous n'avez donc pas à les télécharger. Très bien écrits, ces modules  vous déchargent de l'écriture de dizaines ou de centaines de lignes de code.

En général, pour les solliciter, il vous suffit de saisir \emph{au début de votre programme} la commande \texttt{use} suivie du nom du module.
Exemples:
\begin{verbatimtab}[5]
use locale;
use strict;
use CGI::Carp;
\end{verbatimtab}

Vous n'avez pas à comprendre comment ces modules sont écrits. Il vous suffit de savoir ce qu'ils font. Ils sont aussi documentés: saisissez par exemple dans un terminal la commande \texttt{perldoc locale}.

\subsection{Application: créer vite le lexique d'un fichier}
\subsubsection{Première étape} \label{accent}
Nous avons vu précédemment comment repérer les mots d'un fichier, en prenant comme séparateurs la ponctuation et les espaces. \emph{A priori}, cette démarche est inutile, puisque l'expression régulière \texttt{$\backslash$W} remplit cette fonction. Or, cela n'est pas satisfaisant  avec les caractères accentués. Exemple:
\begin{verbatimtab}[5]
my $a="Bonjour à tous!";
my @listemots=split (/\W/,$a);
print join("T",@listemots),"\n";
#affiche BonjourTTTtous
\end{verbatimtab}

Non seulement le \emph{à} a disparu de nos mots, mais en plus, des mots vides apparaissent. Cet exemple semble prouver que notre démarche précédente était la bonne. Mais il y a une solution plus rapide\notemg{\emph{locale} est un élément de votre système d'exploitation qui précise votre environnement linguistique et votre encodage. Saisissez \texttt{man locale}, \texttt{locale} et \texttt{perldoc locale} pour en savoir plus. Pour imposer un environnement en \emph{latin1}, saisissez la commande suivante dans une fenêtre \emph{terminal}: \\
\texttt{LANG= fr\_Fr}}:

\begin{verbatimtab}[5]
use locale;
my @listemots=split (/\W/,$a);
print join("T",@listemots),"\n";
#affiche BonjourTàTtous
\end{verbatimtab}

\subsubsection{Le programme final} \label{tri}
\begin{verbatimtab}[5]
use locale;
open (F, "le_fichier_dont_je_veux_le_lexique");
open (G,">lexique.txt");
while (<F>)
	{chomp;
	$_=lc($_); #met tout en minuscules(lowercase)
	@l=split(/\W/);
	foreach $u (@l)
		{next if $u eq ""; #conseillé
		$freq{$u}++;
		}
	}	
close (F);	
foreach my $u (sort tridecroissant keys %freq)
	{print G "\"$u\" a pour fréquence $freq{$u}\n";
	}
close (G);	

sub tridecroissant #voir le paragraphe routines
	{$freq{$b} <=> $freq{$a};}
\end{verbatimtab} 

\subsection{Routines}
Ce sont en quelque sorte des fonctions; elles peuvent s'appliquer à plusieurs variables, de types scalaires ou listes\notemg{On peut définir des fonctions qui travaillent sur des tableaux indexés, mais c'est plus technique: voir les \emph{références}.}; mais alors les  scalaires doivent être citées en  premier (sinon la variable la plus sophistiquée absorbe la plus simple). En général, les routines renvoient des variables scalaires ou des listes, mais il y a moyen de se débrouiller pour qu'elles renvoient aussi des \emph{hash}es.

Je  donne quelques exemples simples, qui évoquent en même temps la syntaxe propre aux (sous-)routines.
\subsubsection{Exemple élémentaire}
\begin{verbatimtab}[5]
sub maximum
	{
	my ($a, $b) =@_;
	my $max;
	if ($a < $b)
		{
		$max=$b;
		}
	else
		{
		$max=$a;
		}
	return $max;
	}	
\end{verbatimtab}

\hspace{-1.5cm}\textbf{Explication rapide et remarque}

\texttt{@\_} est une variable prédéfinie qui reçoit tous les paramètres de la fonction définie\notemg{Par convention, on glisse toutes les routines à la fin du programme. Mais ce n'est pas obligatoire. En général, je glisse la définition des routines dans un autre document, que j'appelle avec la fonction \texttt{require}.}.
La ligne contenant \texttt{return} n'est pas indispensable si ce qu'on attend est la dernière variable utilisée.

\medskip
On appelle ainsi la routine constituée: 
\begin{verbatimtab}[5]
my $chose=2;
my $c=maximum ($chose,8);
print $c,"\n";
#affiche 8
\end{verbatimtab}

\subsubsection{Exemple utilisant une liste}
\begin{verbatimtab}[5]
my $a=12;
@liste_de_nombres=(-2,13,6,8);
my $m=maximum2 ($a,@liste_de_nombres),"\n";
print $m,"\n";
#affichera 13

sub maximum2
	{
	my ($a, @liste) =@_;
	foreach my $c (@liste)
		{
		if ($a < $c)
			{
			$max=$c;
			$a=$max;
			}
		else
			{
			$max=$a;
			}
		}	
	return $max;
	}	
\end{verbatimtab}

\subsubsection{Routine de tri}
Cf. le point \ref{tri} et les documentations.
Pour trier dans l'ordre croissant des fréquence le programme de \ref{tri}:
\begin{verbatimtab}[5]
sub tricroissant 
	{
	$freq{$a} <=> $freq{$b};
	}
\end{verbatimtab}
Bien entendu, il faudra modifier la ligne \texttt{foreach}:
\begin{verbatimtab}[5]
foreach my $u (sort tricroissant keys %freq)
\end{verbatimtab}

\subsection{Toujours de l'audace}
Une idée pour intégrer un \emph{hash} dans une routine:
supposez que vous avez un \emph{hash} qui s'appelle \texttt{\%tableau}, et que vous voulez l'appeler par son nom, mais que cela vous apparaît difficile. Pourquoi ne pas tenter de créer une variable qui contient le mot \emph{tableau} et de la précéder d'un \texttt{\%}? Le risque que Perl interprète la chose comme vous l'imaginez est grand.

Exemple:
\begin{verbatimtab}[5]
%tableau= (France => Paris, Allemagne => Berlin);
$mot="tableau";
print %$mot, "\n";
#affiche: FranceParisAllemagneBerlin
print $$mot{Allemagne};
#affiche: Berlin
\end{verbatimtab}

Si vous aimez ce genre d'interprétations, vous adorerez les références.

\section{Conclusion}
Vous avez désormais tous les moyens d'améliorer vos connaissances de Perl en vous plongeant dans les documentations précitées.

\bigskip
\emph{Enjoy}!

\bigskip
\tableofcontents

\end{document}

perl -e 'print 2+2'



\section{Bases du CGI}
Là encore, tout est simplifié au maximum, et ce qui suit n'est donc pas universel.

Sur le serveur, on écrit une page web d'invite, qui propose des paramètres et un bouton «Envoi». 

Sélectionner ce bouton appelle un programme CGI qui s'exécute et renvoie au client ce qu'il désire (le plus souvent, c'est aussi une page web, \emph{dynamique}). 

Tout cela répond à des protocoles qu'il est prudent de  respecter...

\subsection{Exemple de page web d'invite}
Elle respecte la structure de l'html (en-tête, corps, conclusion).
Les bases de l'html sont supposées connues.

Dans le corps, sont glissés les paramètres, la méthode d'appel et le nom du programme CGI.

Visualisez cette page avec un navigateur. \emph{Attention!}: le pdf de ce cours peut induire des espaces justifiantes et des apostrophes non conformes...

Appelons, par convention, la page web suivante \textbf{pageweb.html}

\subsubsection{Un en-tête minimal}
\texttt{~\\
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" \\
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> \\
~\\
<head> \\
<META http-equiv="Content-Type" content="text/html"; \\
charset="ISO-8859-1"> \\
    <title>Ce qui s'inscrit sur le bandeau de la page web</title> \\
  </head>}

\subsubsection{Conclusion}
\texttt{~\\
</html>}

\subsubsection{Exemple de corps}
\texttt{~\\
<body>\\
<h2>Bonjour chère lectrice, cher lecteur. </h2>}

\texttt{~\\
Dans le jargon informatique, vous êtes un <b>client</b>, je suis une page web installée sur un <b>serveur</b>.<p>}

\texttt{~\\
Je vais appeler un programme CGI écrit en Perl qui va: <br>\\
a. vous dire  ce qu'il sait de vous et des protocoles du serveur <br>\\
b. vous montrer comment il reçoit quelques paramètres que je vais vous demander de sélectionner. <p>}

\medskip

\texttt{~\\
<form ENCTYPE="multipart/form-data" \\
ACTION="/cgi-bin/leprogramme.pl" method="post"> \\
<!- - Cet appel par la balise <i>form</i> est essentiel \\
(ceci est un commentaire, comme tout texte entre le symbole\\
«<!- -» et le symbole «- ->») - ->
}

\medskip

\texttt{~\\
Note: il y a deux façon d'appeler un CGI: le \emph{get} et le \emph{post}. Dans le cadre de ce cours, seule la méthode \emph{post} sera utilisée.<p>}
 
 \medskip

\texttt{~\\
<b>I</b>. Choisissez une couleur: \\
  <select name="couleur">\\
    <option selected="selected">Aucune</option>\\
    <option>Bleu</option>\\
    <option>Orange</option>\\
    <option>Vert</option>\\
 </select>}

 \medskip

\texttt{~\\
<p> \\
<b>II</b>. Saisissez maintenant un texte d'une vingtaine de caractères, avec des chiffres et des  diacritiques.<br>\\
<input name="texteduclient" size=30>\\
<p>}

 \medskip

\texttt{~\\
<b>III</b>. C'est maintenant à vous de jouer...<br>\\
 <input type="submit" value="C'est parti !" />\\
  <input type="reset" value="On repart à zéro" />\\
  </form>\\
<!- - Remarquez ici la fermeture de la balise \emph{<form>} - -> 
  <p>}
  
\texttt{~\\
Rien ne nous empêche de continuer à écrire ici du texte, d'insérer des images, etc.<p>} 
 
 \subsection{Exemple de CGI associé}
Les commentaires sont précédés d'un dièse.
On appellera le fichier suivant du nom évoqué dans la balise \texttt{<form>}.
Ce programme s'intitulera donc \textbf{leprogramme.pl}

\texttt{~\\
\#!/usr/bin/perl \\
\#Faux commentaire indispensable pour les cgi: \\
\#il précise où est Perl (cf. which perl)}

\texttt{~\\
\#\#\#\#\# Dialogue essentiel pour le navigateur client\\
print "Content-type: text/html$\backslash$n$\backslash$n"; \\
\# Ne pas oublier les 2 RC, sinon ça ne fonctionne PAS !!!}

\texttt{~\\
print "<!DOCTYPE HTML PUBLIC $\backslash$"-//W3C//DTD HTML 4.0 \\
Transitional//EN$\backslash$" \\
$\backslash$"http://www.w3.org/TR/REC-html40/loose.dtd$\backslash$"> \\
<html> \\
<head> \\
<meta http-equiv=$\backslash$"Content-Type$\backslash$" content=$\backslash$"text/html$\backslash$"; charset=$\backslash$"ISO-8859-1$\backslash$"> \\
<title>Premier CGI</title> \\
</head> \\
<body>$\backslash$n"; \\
\# En-tête minimal d'une page web}
 
\texttt{~\\
\#\#\#\#\# Affichage de \%ENV \\
print "<h1>Informations sur le client et le serveur</h1>$\backslash$n"; \\
foreach \$u (keys \%ENV) \\
	\{~\\
	print "la variable \$u a pour valeur \$ENV\{\$u\}<br>$\backslash$n" \\
	\}
	}

\texttt{~\\
\#\#\#\#\# Affichage brut de la page reçue (voir le source)\\
read (STDIN, \$requete, \$ENV\{'CONTENT\_LENGTH'\}); \\
print "<h1>Ce qui est transmis au serveur</h1>$\backslash$n"; \\
print \$requete;
}

\texttt{~\\
\#\#\#\#\# Fin \\
print "<p>Vous savez maintenant séparer les champs de votre page web, récupérer les paramètres sélectionnés par l'utilisateur, retrouver son numéro IP, éventuellement faire un filtrage suivant son système d'exploitation, etc.<br>"; \\
print "<p>$\backslash$n</body></html>$\backslash$n";
}


\subsection{Association entre les deux fichiers}
Ces deux fichiers ne sont pas posés n'importe où. Le fichier html doit être dans l'espace éditorial du serveur (ex.: \texttt{/var/www/html, public\_html \\
/usr/local/apache/htdocs/undossierquelconque}).

Le programme CGI doit aussi être dans un endroit spécifique, d'autant que l'appel à \texttt{/cgi-bin/} dans la page html renvoie en fait à un dossier précis (ex.: \\
\texttt{/usr/local/apache/cgi-bin/}, 
\texttt{/Library/WebServer/CGI-Executables}).

Tout cela est précisé dans le fichier \texttt{httpd.conf}, qui est en général au n\oe ud au dessus des dossiers html et cgi (ex.: \texttt{/usr/local/apache}).

Et bien sûr, pour implémenter, adapter, modifier ces deux fichiers, il faut connaître des rudiments d'Unix. Par exemple, on oublie souvent que le CGI doit être exécutable par tous:
\texttt{chmod a+x leprogramme.pl}


 
\subsection{Quelques logiciels}
Déjà, une remarque pour Perl: \texttt{perl -c leprogramme}, et \texttt{perl -cw leprogramme} mènent souvent à des commentaires du compilateur fort instructifs.

Un programme s'appelle de deux façons possibles: en cliquant sur son icône (si on la trouve), en l'appelant par son nom.

Exemple: \texttt{nedit}, \texttt{nedit \&} (mieux!), \texttt{emacs \&}, \texttt{mozilla \&}.

Parfois, il faut préciser le chemin d'accès au programme.

Ex.: \texttt{/bin/mv}, \texttt{./monprogramme}


 
\end{document}



