# Programmation Perl/Version imprimable

* Si vous imprimez cette page, choisissez « Aperçu avant impression » dans votre navigateur, ou cliquez sur le lien Version imprimable dans la boîte à outils, vous verrez cette page sans ce message, ni éléments de navigation sur la gauche ou en haut.
* Cliquez sur Rafraîchir cette page pour obtenir la dernière version du wikilivre.
* Pour plus d'informations sur les version imprimables, y compris la manière d'obtenir une version PDF, vous pouvez lire l'article Versions imprimables.
Une version à jour et éditable de ce livre est disponible sur Wikilivres, une bibliothèque de livres pédagogiques, à l'URL : https://fr.wikibooks.org/wiki/Programmation_Perl

# Introduction

<< Retour au sommaire
Perl (Practical Extraction and Report Language ou langage pratique d'extraction et de génération de rapports) est un langage de programmation créé par Larry Wall en 1987 et reprenant des fonctionnalités du langage C et des langages de scripts sed, awk et shell (sh). Bien que son nom soit l'objet de plusieurs acronymes on l'utilise généralement avec un P majuscule pour désigner le langage et un p minuscule en parlant de l'interpréteur. « Seul perl analyse correctement Perl ».

## Origines et implémentation

Perl est né du besoin de disposer d'un langage optimisé pour l'extraction d'informations de fichiers textes et la génération de rapports.
Une de ses devises est « There Is More Than One Way To Do It (TIMTOWTDI) » qui pourrait se traduire par « Il y a plus d'une façon de le faire ». Ce qui est un point fort d'après les adeptes puisque chacun peut écrire du code comme il l'entend. Bien entendu, ceci peut être vu comme un point faible puisque ça donne lieu à différents styles très différents de code et pour le lecteur qui lira des codes de différents programmeurs, il faut s'adapter.
Une autre est « Perl : le couteau suisse des langages de programmation ». Sa souplesse autorise l'emploi de plusieurs modèles de programmation : programmation procédurale, programmation fonctionnelle et POO---bien que les puristes de ce dernier ne considèrent pas Perl comme en faisant partie, son objectif est de s'adapter aux goûts du programmeur plutôt qu'une architecture stricte du langage. Perl est souvent considéré comme le langage de script par définition et a été qualifié de "ciment assurant la cohésion du web", étant un des langages CGI les plus populaires.
Un autre point qui ne fait pas consensus est le nombre de raccourcis dans le langage Perl pour écrire du code plus rapidement et de façon élégante. Mais l'usage trop courant de ces raccourcis rend le code plus difficile à appréhender pour un non averti.
Perl est un logiciel libre, distribué sous licence artistique et GPL. Perl est porté sur la plupart des systèmes d'exploitation mais excelle particulièrement en environnement UNIX et ses dérivés; il gagne aussi en popularité sous Microsoft Windows. Un exemple du champ d'action de Perl est son utilisation comme script CGI pour faire tourner Wikipédia jusqu'en janvier 2002.
Une immense collection de modules Perl d'utilisation libre, allant des mathématiques avancés aux connexions aux bases de données, en passant par les réseaux et bien davantage encore, peuvent être téléchargés depuis un réseau de sites appelé CPAN.
Bien que Perl profite de la plupart des facilités d'un langage interprété, à proprement parler il n'interprète et n'exécute pas le code source une ligne à la fois. En fait, Perl compile d'abord le programme entier dans un bytecode intermédiaire (assez dans l'esprit du code objet Java), l'optimisant au passage, et exécute alors ce bytecode. Il est possible de compiler un programme Perl en bytecode pour s'épargner les phases de compilation lors d'exécutions futures, bien que l'« interpréteur » est toujours requis pour exécuter ce code.
Perl 6 est en cours de développement. Il tournera dans la machine virtuelle Parrot.

## Ce qu'il faut savoir sur ce livre
### Le but

Le but de ce livre est de fournir une documentation suffisante pour maîtriser en grande partie le langage Perl dans sa version 5 (à partir de la version 5.10). Il présentera la base du langage en premier lieu, puis quelques aspects avancés entrecoupés de tutoriels et travaux pratiques divers afin d'entraîner le lecteur à l'écriture de scripts divers. Le tout sera agrémenté d'un nombre conséquent d'exemples, de bonnes pratiques à adopter, d'indications sur les bibliothèques logicielles les plus utiles, et toute information qui nous semblera pertinente.

### Les exemples présentés

Nous utiliserons la version 5.14 de l'interpréteur perl.
Tout code présenté ici commencera par ces 4 lignes qui seront présentées dans les bases du langage :
Je ne les répèterai pas pour ne pas alourdir chaque exemple (qui seront nombreux), si vous souhaitez exécuter le code présent dans ce livre n'oubliez pas de les écrire en premier dans votre code. Cela fait partie des bonnes pratiques de programmation en Perl.

## Pour les débutants

Vous voulez apprendre à programmer des applications, et ceci est votre premier livre sur le sujet. Voici quelques informations de base sur la programmation.

### Votre premier éditeur de texte

Tout d'abord, pour programmer il faut un éditeur de texte. N'importe-quel éditeur de texte suffit pour programmer, cependant il est conseillé que votre éditeur de texte ait au moins la coloration syntaxique du langage que vous apprenez (ici Perl). Il en existe un nombre assez conséquent, mais voici quelques pistes :
* avec une interface graphique
   * gedit : simple, possède une coloration syntaxique, suffisant, existe sous Linux
   * Notepad++ : simple, pour les gens sur Windows
* sans interface graphique (en ligne de commande sous GNU/Linux ou Unix)
   * vim : très puissant mais nécessite un petit temps d'adaptation
   * emacs : comme vim

### Comment bien apprendre

Vous allez apprendre à programmer dans un certain langage de programmation. Avant de commencer, il faut savoir que cela va prendre du temps, et qu'il ne faut pas se précipiter. Lisez bien chaque exemple, essayer de modifier tous les bouts de code présentés en les complexifiant de plus en plus, essayez de faire tous les exercices et prenez le temps qu'il vous faut. Ce n'est pas une course, passez deux à trois heures maximum à apprendre par jour, c'est amplement suffisant.

# Bases du langage
## Bonjour !

L'un des plus petits programmes possible en langage Perl est :
(Les numéros de lignes ont été ajoutés pour la lisibilité, mais ne font pas partie du programme.)
Ce programme a pour seul but d'afficher le texte « Bonjour ! » suivi d'un retour à la ligne. Voici la description de chaque ligne qui le compose :
Ceci s'appelle un shebang et est destiné à déterminer quel est l'interpréteur à utiliser pour comprendre les instructions qui suivent.
Ceci décrit respectivement les conventions d'écriture (strict), l'affichage de message d'avertissement (warnings), ainsi que l'utilisation d'une certaine version de l'interpréteur Perl. Maintenant que vous savez ceci, vous comprenez que les 4 premières lignes ne sont pas toujours strictement nécessaires mais que cela fait partie des bonnes pratiques de les écrire. Pour cela, comme dit dans l'introduction, il faut inclure ces 4 lignes en début de chaque programme que vous écrirez.
Affiche simplement la chaîne de caractères Bonjour !. Le mot clé réservé say permet d'afficher une chaîne de caractères suivit par un retour à la ligne.
À noter qu'à l'exception de la première ligne, chaque autre ligne se termine par un point virgule, désignant comme dans beaucoup d'autres langages de programmation la fin d'une instruction.

## Compilation

Pour pouvoir exécuter un programme Perl, il faut soit l'exécuter via la commande perl fichier_perl.pl soit on rajoute le shebang (vu plus haut), on rend le fichier exécutable chmod +x fichier_perl.pl puis on l'exécute ./fichier_perl.pl.

## Éléments de syntaxe
### Commentaires
#### Sur une ligne

Les commentaires se font sur une ligne et commencent à partir du caractère dièse # .

#### Sur plusieurs lignes : POD

Écrire un commentaire sur une ligne c'est pratique lorsque nous avons très peu de commentaire à faire, mais nous avons parfois besoin de beaucoup plus d'une ligne pour écrire une explication un peu plus longue. Dans ce cas, il est possible d'utiliser un mécanisme intégré à Perl qui a été conçu pour que les scripts comportent directement leur propre documentation : POD (Plain Old Documentation - Bonne Vieille Documentation). Avec ce système, nous allons écrire notre propre documentation directement au milieu de nos lignes de code (comme il se fait de nos jours dans un bon nombre d'autres langages).
À savoir que tout code est commenté de cette manière sur le CPAN, le plus gros rassemblement de modules Perl. Nous reverrons le CPAN et les modules qui permettent de réutiliser du code déjà écrit (même par d'autres développeurs) plus tard.
Un exemple simple d'instructions POD (se trouve au milieu d'un code) :
La structure est très simple, on commence par =pod, un saut de ligne, on écrit nos commentaires, un saut de ligne et on termine par =cut. Cela permet d'écrire de la documentation très facilement, puis de la convertir en html pour la voir dans un navigateur web par exemple.
La directive =pod déclare le début du commentaire, =cut la fin (et donc la reprise de l'interprétation du code Perl).
Sachez qu'il est possible de faire de la documentation bien plus structurée que simplement plusieurs paragraphes séparés par un saut de ligne, afin qu'un formateur de code POD puisse le transformer en fichier LaTeX ou HTML plus facilement compréhensible. Cependant pour ne pas alourdir ce livre, je vous renvoie sur quelques tutoriels dont les liens se trouvent dans les ressources.

### instructions

Chaque instruction est séparée par un point virgule (;). Les blocs d'instructions commencent par une accolade ouvrante ( et se terminent par une accolade fermante). Contrairement au langage C, les instructions ne sont pas toujours dans ces blocs, nous verrons ça plus tard.

### déclaration de variables
#### portée des variables

Le mot clé my désigne une portée locale, c'est à dire limitée à un bloc d'instructions. Le mot clé our désigne une portée globale, c'est à dire visible partout dans le fichier (dans les différentes fonctions, par exemple). Lorsqu'une variable est visible, elle est lisible et modifiable.

# Types de base
## Les types

En Perl il n'y a que 3 types de base. Ils sont reconnaissables à leur sigil, qui est un caractère avant le nom de la variable ($, @, %). Nous parlerons également de références qui est un moyen, comme son nom l'indique, de faire référence à une autre variable (proche de la notion de pointeurs en C).

### Scalaire

Sigil : $ . Le type scalaire est un type qui peut garder en mémoire diverses informations. Exemple :

#### Déférencement sur scalaire
### Référence

Une référence est un scalaire qui permet d'accéder à l'adresse mémoire où est stockée un autre scalaire, un tableau, un tableau associatif ou même une fonction. C'est très utilisé pour passer des tableaux en paramètre d'une fonction, ou tout autre élément que nous souhaiterions modifier sans passer par des copies de leurs valeurs. Nous allons voir par la suite comment les manipuler.

### Tableau

Sigil : @ . Un tableau permet de stocker une liste. Une liste permet de stocker plusieurs éléments (des scalaires, des références). Une liste peut également être stockée dans un tableau associatif.
Voyons d'abord les tableaux :

#### accéder à une valeur d'un tableau

Il suffit d'utiliser les crochets et d'indiquer l'indice de l'élément recherché. À retenir : la numérotation commence à 0.

#### Déférencement de tableau
### Tableau associatif

Sigil : % . Un tableau associatif (ou table de hashage) est un type qui permet d'associer un scalaire à un autre.

#### Déférencement de tableau associatif
## Contexte

En Perl, la notion de contexte est importante et très utile. Suivant comment vous faites appel à la une variable, suivant l'opérateur que vous utilisez ou l'expression utilisée, vous faites appel à un contexte particulier. Petite présentation des contextes les plus utilisés.

### Contexte numérique

L'expression évaluée est considérée comme un nombre. Les opérateurs utilisés traiteront les scalaires comme des nombres, ainsi la chaîne de caractères 01.50 sera interprétée comme le nombre 1.5. Dans ce contexte, les listes et les tableaux renvoient leur nombre d'éléments. Dans ce contexte, la valeur renvoyée par un élément de type undef est 0.

### Contexte (scalaire) de chaîne

Un nombre est considéré comme une chaîne, et nous pouvons par exemple l'afficher, l'insérer dans une autre chaîne, etc. Dans ce contexte, la valeur undef renvoie la chaîne vide : "".

### Contexte de liste

Comme son nom l'indique, il permet de manipuler des listes et également les tableaux. Dans ce contexte, une liste renvoie ses éléments. Si une liste est undef alors elle renvoie une liste d'un élément undef.

### Exemples

Un certain nombre d'opérateurs forcent le contexte.

#### contexte (scalaire) numérique

Une manière de forcer le contexte scalaire est d'utiliser la fonction scalar.

#### contexte de liste

À noter qu'il est possible de forcer le contexte de liste avec un scalaire comme variable à gauche de l'affectation.
Précision : my ($a, $b, $c) = (1, 2, 3) est une façon correcte de faire des déclarations multiples et simultanées de variables.

# Fonctions sur listes
## Rappels sur les listes

Une liste est une suite de mots, de nombres… tout scalaire à vrai dire. Une liste stockée forme un tableau ou un tableau associatif (que nous verrons plus loin).

### une liste

Pour créer une liste on utilise les parenthèses de cette manière :
Nous avons là une suite de scalaires : "5.0", "truc", 7 et la valeur stockée dans la variable scalaire $autre_valeur.

### créer un tableau

Pour pouvoir la manipuler plus tard dans le programme, nous la stockons dans une variable. La variable est donc un tableau signalé par le sigil @.
Exemple avec parenthèses :
Mais il y a d'autres opérateurs dédiés à la création de listes, comme qw qui crée une liste de mots (quoted words). Cet opérateur est préféré aux parenthèses dû à sa concision.
Exemple avec qw :
La création de la liste est plus concise. Mais ceci va plus loin encore (voir la création de tableaux associatifs avec qw).

### Créer un tableau associatif

Un tableau associatif (ou table de hachage) est une structure permettant d'associer à un scalaire un autre scalaire. C'est une liste un peu plus complexe qu'un tableau et le sigil est différent (%).
La création de ce type de liste se fait également avec des parenthèses, mais on ajoute également (facultatif) un opérateur => pour voir facilement la clé et sa valeur :
À savoir : l'opérateur => force l'interprétation de la variable à sa gauche comme une chaîne de caractères, donc les guillemets sont inutiles. Même exemple, mais avec qw :
Là encore nous voyons la concision apportée par cet opérateur. %bon_a_manger a le sigil % donc Perl sait qu'il doit ranger les mots par paires de la manière clé-valeur ("fruit" => "cerise", "légume" => "patate").

## Fonctions de manipulation de listes

Il existe un nombre assez conséquent de fonctions de manipulation de listes (tableaux, tableaux associatifs). Nous allons aborder les plus courantes. Il n'est pas obligatoire de les connaître toutes par cœur.

### .. : créer une suite d'éléments

On pourrait vouloir par exemple créer des suites longues d'éléments qui s'enchaînent. Par exemple, avec l'opérateur .. écrire une suite de 1 à 100 n'est pas plus compliqué que :
Nous pouvons faire également la même chose avec des lettres :

#### exemple : les lettres de 'a' à 'zz'

Nous allons afficher à l'écran toutes les combinaisons des lettres de 'a' à 'zz' :

### join : concatène tous les éléments d'une liste

La commande join permet de concaténer tous les éléments d'une liste avec un motif (une chaîne de caractères par exemple) entre chaque élément.
Exemple : afficher tous les éléments d'un tableau séparés par un double point.
Affichera : « poire : cerise : pomme : fraise ».

### map : transforme tous les éléments d'une liste

Conseil : pour comprendre correctement cette fonction, voyez au moins le cours sur les fonctions et les procédures.
Cette fonction applique une transformation à tous les éléments d'un tableau ou d'une table de hachage. map prend en argument un bloc de code à exécuter et une liste (ou tableau). Il retourne une liste d'éléments modifiés.
Un exemple simple, on va doubler les valeurs d'un tableau :
Comme plus haut mais en une seule ligne :
Écrire du code aussi compact est très pratique à l'usage, mais pour un débutant il n'est pas nécessaire de savoir écrire de façon aussi concise.

### grep : récupère une partie des éléments d'une liste

Se manipule comme map, et permet de récupérer une liste d'éléments contenus dans une liste suivant certaines conditions. Exemple : les éléments numériques inférieurs à 10 :

### exists : savoir si un élément d'une liste existe

Cette fonction permet de savoir si un élément d'une liste existe. Attention : ceci ne permet pas de savoir si l'élément est défini.

### keys : retourne toutes les clés d'une table de hachage

Renvoie une liste des clés d'une table de hachage.
Affiche : « légume : fruit ».

### values : retourne toutes les valeurs d'une table de hachage

Renvoie une liste des valeurs contenues dans une table de hachage.

### each : retourne un couple clé-valeur d'une table de hachage

Cette fonction est très utile pour boucler sur tous les éléments d'un tableau associatif.
Affichera : « Un couple 'clé - valeur' : légume - carotte » .

### pop : retire le dernier élément d'une liste et le retourne

Permet de supprimer le dernier élément d'une liste. Il retourne cet élément, donc on peut le récupérer.

### push : ajoute à la fin de la liste un nouvel élément

Cette fonction ajoute un élément à la fin d'une liste.
On reprend l'exemple plus haut en ajoutant push pour remettre « fraise » :

### shift : supprime le premier élément d'une liste et le retourne

Il suffit de faire shift @tableau, exemple :

### unshift : ajoute un élément au début d'une liste

Exemple simple d'utilisation de unshift :

### reverse : inverse tous les éléments d'une liste (le dernier devient premier, etc.)

On fait simplement reverse @tableau.
Le tri alphabétique inverse en devient on ne peut plus clair.

### scalar : retourne le nombre d'éléments d'une liste

Cette fonction n'a aucune utilité si on est en contexte scalaire, par exemple :
Cependant, lorsque nous sommes en contexte de liste, il sera déjà plus utile :
Ici, le code que nous avons créé permet de créer un tableau @nombres_elements qui contient le nombre d'éléments de deux précédents tableaux. Sans scalar, nous aurions un tableau contenant l'ensemble des scalaires des deux premiers tableaux. Cela est dû à l'aplatissement des tableaux.

### sort : ordonne une liste
# Opérateurs
## Opérateurs numériques

Perl reprend tous les opérateurs classiques (+, -, *, /, %, sin, cos) et les étend. Il y a des raccourcis utiles à connaître pour l'affectation, comme ++, --, +=, -=, *=, %= Il existe également l'opérateur exponentiel **.

### exemples

Il faut être attentif aux opérations avec ++ et -- . $b = $a++ affecte à $b la valeur de $a **avant** son incrémentation. $b = ++$a affecte à $b la valeur de $a **après** son incrémentation.

## Opérateurs de chaînes

Les opérateurs les plus basiques qui travaillent sur des chaînes sont :
* . : concaténation
* length : connaître la taille d'une chaîne
* chop : retire le dernier caractère d'une chaîne
* chomp : comme chop mais seulement si le dernier caractère est un retour à la ligne
* split : permet de couper une chaîne suivant un motif
* join : regroupe les éléments d'une liste, avec une chaîne entre tous les éléments
* reverse : inverse les éléments d'une liste (le premier devient le dernier et inversement)
* substr : prend une partie de la chaîne
* index : cherche l'indice de la première occurrence d'une chaîne dans une autre
* rindex : inverse de la fonction index, cherche la dernière occurrence

### exemples
#### explications

Ici, nous appellons la fonction say pour qu'elle affiche la taille de la chaîne de caractères $str (7), un espace (" ") et l'index de la première occurrence de "uc" (2). Nous verrons plus tard comment se passent les passages de paramètres et retours de fonctions.
La fonction split permet de séparer une chaîne de caractères suivant un motif, ici la chaîne vide : "". Ceci a pour conséquence de séparer toutes les lettres.
Nous affichons le retour de la fonction join qui renvoie tous les éléments de @tableau_de_caracteres séparés par la chaîne " | ". Elle affiche donc "c | o | u | c | o | u".

# Tests
## Les tests

Il existe plusieurs manières d'effectuer un test, qui est couramment appelé « évaluer une expression » en jargon informatique. Nous allons voir les méthodes les plus courantes.

### Les mots clés

* if, elsif, else, unless
Le mot clé utilisé pour faire des tests est if (ou unless si on veut tester négativement). Si le test échoue, nous pouvons mettre la condition "sinon si" : elsif. Nous pouvons enchaîner autant de elsif que nous le souhaitons. Un bloc de code est exécuté si tous les autres tests précédents ont échoué via le mot clé else. Unless peut être vu comme l'inverse de if (si n'est pas).

### Syntaxe
#### Syntaxe classique if elsif else

Nous allons voir comment effectuer des tests et exécuter différentes parties du code en fonction des valeurs de nos variables. Cette syntaxe est particulièrement connue car utilisée dans de nombreux langages.
Attention : il ne faut pas mettre de point virgule (;) à la fin de toutes les lignes, relisez bien le code pour savoir où les placer ! Contrairement à certains langages, nous ne pouvons pas ommettre les accolades () dans cette version du test.

##### exemple
#### condition après instruction conditionnée

Ce code est bien plus court, et avec cette syntaxe nous n'avons pas besoin de mettre les parenthèses.

##### exemple

Ce code affiche "6" car $a > $b. Cependant, cette façon d'écrire le test d'une série d'expressions ne permet pas l'utilisation de elsif, de else, et ne permet l'exécution conditionnelle que d'une seule instruction.
Cette méthode permet de lire l'instruction conditionnée comme si on lisait une phrase => "fais ceci SI cela".

#### Syntaxe condition ternaire
##### exemple

$a ( valeur = 6) est plus grand que $b (valeur = 5) donc on affiche "$a plus grand que $b".

### Opérateurs de tests

Il y a un certain nombre d'opérateurs qui permettent de faire des tests sur des nombres (scalaires numériques), des chaînes (toujours des scalaires) ou des listes.

#### Opérateurs de tests numériques

Tout d'abord, les tests de comparaisons classiques comme dans les autres langages (et en mathématiques) :
Ils nous permettent de faire des tests très simples "si $a plus grand que $b". Un peu moins répandu :

#### Opérateurs de tests sur chaînes

Ces opérateurs travaillent sur des chaînes de caractères. Une chaîne "plus petite" qu'une autre est une chaîne qui apparaît avant dans l'ordre lexicographique.
* lt (plus petit que) , gt (plus grand que),
* le (plus petit ou égal) , ge (plus grand ou égal) ,
* eq (égal) , ne (non égal).

##### valeurs booléennes retournées: 1 ou vide
#### Opérateurs pour tester plusieurs expressions

Commençons par les mots clés :
* or, and, : « ou » et « et »
* ||, && : « ou » et « et »
Nous verrons plus tard la notion de précédence.
Ce qu'il faut savoir pour évaluer plusieurs expressions est que l'on peut combiner des expressions pour en former une seule grande. Comme nous l'avons vu, une expression est souvent un test entre parenthèses :
Nous pouvons créer une expression plus grande, combinant celle-ci avec d'autres :
Ici, nous évaluons la première expression ($a >= $b) et avec le « ou » (les deux barres verticales ||) nous évaluons la seconde expression seulement si la première a échouée ($a est un nombre inférieur à $b). Si à la place du « ou » (||) nous avions un « et » (&&), il faudrait que les deux expressions qui l'entourent soient testées positivement pour que l'expression globale soit vraie.

##### exemple

On affiche $a si ($a est inférieur à $b et que son double ($a * 2) est supérieur à $b) ou si $a est égal à 5. $a ne correspond pas au premier test entre parenthèses ($a < $b && ($a * 2) > $b) car une des deux conditions nécessaires n'est pas remplie. Donc le premier test est négatif et on va exécuter la seconde série de tests après le « ou » (||), $a est égal à 5, donc la série globale est validée. On affiche 5 (la valeur de la variable $a).

# Itérations
## Boucles et syntaxe

Les boucles permettent simplement de ré-exécuter un bloc de code. Perl offre des outils très puissants pour parcourir aisément des listes (tableaux, tableaux associatifs).

### Boucle while et until

Boucle classique, déjà vue dans un bon nombre de langages.

#### Syntaxe

La seule différence entre while et until est que while boucle tant que l'expression est vraie, until jusqu'à ce qu'elle le soit.

#### exemples

Tant qu'il reste des éléments dans @fruits on boucle, et à chaque itération on pop (suppression du dernier élément d'une liste) un élément qu'on affiche.

### Boucle for

Permet de boucler comme dans le langage C.

#### Syntaxe

La première expression est ce qui est effectué avant de commencer à boucler, la seconde est un test qui est effectué à chaque début de boucle, pour savoir si on continue de boucler, la dernière est une expression qui s'effectue à chaque fin d'itération.
Vous aurez remarqué que les 3 expressions sont écrites entre crochets, c'est parce qu'elles sont toutes les 3 facultatives.

#### exemples
##### explications

Première expression : on crée la variable $i qu'on initialise à 0. Seconde expression : on teste si $i est inférieure à la taille de @fruits. Dans cette condition, on utilise l'opérateur numérique < qui force le contexte scalaire, donc @fruits renvoie son nombre d'éléments. Troisième expression, on incrémente $i (à chaque fin de boucle).
On affiche la ième valeur de la liste @fruits. Ceci se rapproche de la manière de boucler sur des listes et tableaux dans d'autres langages.

### Boucle do while

La différence entre une boucle while comme vu plus haut et une boucle do while est qu'on rentre déjà une première fois dans la boucle même si la condition du while n'est pas vraie.

#### exemples

On effectue la boucle de toutes façons une fois. Si $indice est déjà égal ou supérieur à $valeur_max on l'affichera au moins une fois.

### Boucle foreach

Permet de parcourir toute une liste (tableau, tableau associatif).

#### exemples

Un exemple simple pour montrer la concision d'un code Perl. Nous verrons plus loin les mécanismes qui permettent ceci :

### Boucle sur un tableau associatif

Il y a plusieurs façons de faire.

#### exemples

En utilisant foreach et keys :
Contrairement à "for", l‘ordre de sortie est aléatoire, néanmoins tout y est !
Avec while et each :

# Fonctions et procédures
## Introduction
### Quelques définitions

Déjà, il est bon de savoir ce qu'est une fonction. Une fonction permet de factoriser du code, si on a besoin d'exécuter une même portion de code à des endroits différents, ou pour simplifier la lecture d'un code, il est préférable de séparer certaines instructions et d'y faire appel le moment venu.
Petit instant vulgarisation : un exemple simple pour se représenter ce qu'est une fonction est de s'imaginer toutes les actions que nous avons besoin de faire pour aller faire les courses au marché. Vous dites « aller faire les courses » et pas « prendre mes clés, mon argent, sortir de chez moi, fermer la porte, prendre la voiture … ». Une fonction permet donc ceci: « s'abstraire » de toutes les actions entre le moment où vous partez et le moment où vous revenez. Ce qu'il faut pour que cette série d'action se déroule bien, ce serait avoir un peu d'argent ; prenez ceci comme exemple de paramètre. Pour aller faire les courses (la fonction), il faut un peu d'argent (paramètre de la fonction), et à la fin vous avez vos courses (retour de fonction).

### Ce qu'est une fonction en Perl

En Perl, il y a plusieurs manières d'appeler ou même de faire des fonctions, tout comme il y a plusieurs manières de tout faire. Il n'y a pas forcément une méthode meilleure que l'autre, si ce n'est au niveau de la visibilité du point de vue d'un œil non averti.
Nous commencerons à voir comment se fait l'appel d'une fonction (que nous avons vu sans en parler jusque-là), puis comment créer sa propre fonction et comment récupérer les paramètres.
À savoir : généralement en Perl nous parlons de « routine » pour dire une fonction que vous créez vous-même. Le mot « fonction » est généralement utilisé pour parler des fonctions intégrées directement dans le langage.

## Les appels de fonction

Nous avons déjà vu comment appeler une fonction, par exemple :
Ici nous avons un appel à la fonction "say" et nous passons en paramètre "hello !". Plus classiquement dans les autres langages, des parenthèses sont utilisées pour distinguer la fonction de ses paramètres, ceci donnerait :
En Perl, il n'y a pas d'obligation. Pour passer plusieurs paramètres, Pour enchaîner plusieurs fonctions à la suite, il est parfois nécessaire de mettre des parenthèses pour lever l'ambigüité sur quels sont les paramètres utilisés pour quelle fonction.
Si on cherche à écrire cette fonction de manière plus claire, ceci donne :
On remarque plus facilement la différence entre les paramètres de say et ceux de join. Aussi, si on avait envie que join ne prenne que ':' et qw/mots du milieu/ en paramètre, il aurait fallu écrire :
Assez souvent une fonction renvoie une valeur. Dans l'exemple précédent, la fonction join renvoie une chaîne de caractères (un scalaire) et on réutilise tout de suite cette valeur comme paramètre à l'appel de la fonction say. On aurait évidemment pû récupérer cette valeur :

## Créer une fonction
### Syntaxe

Cela se fait avec le mot clé sub (pour « subroutine » ) suivit du nom que vous souhaitez donner à la fonction, puis d'un bloc de code. La syntaxe la plus simple est :
Il n'y a pas de règle pour le placement des accolades, vous pouvez très bien mettre l'accolade ouvrante sur la même ligne que le nom de la fonction que vous créez si vous trouvez ça plus naturel.

### Récupérer des paramètres envoyés à la fonction

Maintenant on va vouloir passer des paramètres à notre fonction. Il faut savoir qu'en Perl, il n'y a pas besoin d'indiquer les paramètres d'une fonction.
Pour récupérer les paramètres d'une fonction, vous pouvez prendre les valeurs qui se trouvent dans la variable spéciale @_. Cette variable fait partie des variables qui changent au cours du temps, en fonction du moment où elles sont appelés. Dans ce contexte (rien à voir avec les contextes des variables), @_ vaut simplement la liste de paramètres que vous envoyez à votre fonction. Comme cette variable change au cours du temps, il est préférable d'en faire une copie dans un tableau en tout début de fonction, pour récupérer les paramètres et être sûr de pouvoir les réutiliser par la suite.
Donc tout ce que vous avez à faire pour récupérer des paramètres c'est de récupérer @_. À savoir qu'il y a quelques petites astuces à connaître pour récupérer des paramètres facilement. Prenons un exemple, une fonction qui fait une addition (et prend 2 paramètres) et affiche le résultat :
Ici on peut voir qu'il y a des parenthèses autour des deux variables $a et $b ; ceci est pour forcer le contexte de liste. S'il y a plus de deux éléments dans @_ alors ils seront ignorés.

### Retour de valeur

Pour que la fonction retourne une valeur, il suffit d'utiliser le mot clé return. On peut renvoyer un scalaire, une liste (tableau, table de hachage…).
Il est possible également de renvoyer plusieurs valeurs, elles seront renvoyés dans une liste et la récupération de ces valeurs peut se faire comme pour la récupération des paramètres dans une fonction.
Pour renvoyer plusieurs résultats, il suffit de séparer les variables par des virgules, ce qu'on fait généralement pour séparer des paramètres à l'appel d'une fonction par exemple.

# Les modules
## Ce que sont les modules

Un module est une sorte de bibliothèque logicielle, qui possède des fonctionnalités réutilisables. Cela se présente sous la forme d'un fichier, où des tas de fonctionnalités sont écrites et qui touchent toutes à un type d'application, un protocole réseau, un usage, une thématique. Ce qui veut dire qu'un jour une personne a programmé un ensemble de fonctions qui vous permettent de faire quelque chose en particulier, comme par exemple créer une interface graphique ou jouer de la musique, et vous pouvez réutiliser le travail déjà réalisé, ce qui vous permet de gagner du temps.
Nous nous occuperons plus tard de la manière de créer un module, ici on va voir comment les utiliser.
Avant de commencer, sachez que les modules sont recherchés dans des répertoires. Cette liste est dans la variable globale @INC (INC pour include), pour l'afficher :
L'ordre des répertoires est important, car si deux modules du même nom se retrouvent dans deux répertoires différents, seul le premier trouvé sera utilisé. Vous avez également la commande :
Cette commande vous permettra d'obtenir beaucoup plus d'informations, n'hésitez pas à essayer cette commande.
Une fois que vous avez installé Perl, vous possédez une « distribution de Perl », ce qui veut dire que vous avez déjà un certain nombre de modules les plus utilisés.

## Connaître les modules déjà installés sur le système

Il y a deux options de perldoc à connaître pour savoir quels sont les modules installés. La première est pour savoir quels sont les modules installés par défaut avec votre « distribution » de Perl :
La seconde est pour connaître les modules installés en plus (ceux que vous avez installé ainsi que les modules qui ont été installés en tant que dépendance à ces modules).

## Installer un module

Pour installer des modules, je vous conseille d'installer le logiciel cpanminus qui permet d'installer très simplement n'importe quel module en tapant simplement :
cpanminus gère également le téléchargement et l'installation des dépendances du module que vous cherchez à obtenir, il n'y a rien à faire.

### Comment installer cpanminus

    Sous linux (TODO : à vérifier) (pensez à aller voir le site de votre distribution)

## Utiliser un module

Pour utiliser simplement un module :
Prenons la ligne 2, ce que ce code fait est qu'il va chercher dans une liste de répertoires le dossier « Le » dans lequel il y aurait le fichier « Module.pm » (.pm pour Perl Module).
Une fois le module chargé, il ajoute des mots dans notre espace de nommage, c'est à dire qu'il nous permet d'appelé de nouvelles fonctions.
Une fois que vous avez chargé un module, vous ne pouvez plus le décharger.

### un exemple concret

On va chercher le répertoire courant via le module Cwd et la fonction getcwd.
Si on n'avait pas inclut le module Cwd on n'aurait pas la fonction getcwd (pas dans notre espace de noms, fonction inconnue).

## Voir la documentation d'un module

Vous pouvez voir la documentation de n'importe quel module en tapant :
perldoc Le::Module
Réponse :

## Où trouver des modules

On ne va voir ici que des sites où tous les modules sont gratuits et que vous pouvez utiliser librement. Pour trouver des modules et donc des bouts de programme déjà fait, vous avez deux sites web qui sont les références en Perl à savoir :
* search.cpan.org, CPAN (Comprehensive Perl Archive Network) : beaucoup de modules ;
* Méta-CPAN : apporte des outils très intéressants pour choisir le bon module dans l'annuaire du CPAN ;
À savoir : chacun des modules est documenté avec POD (rappel : Plain Old Documentation) et ces sites vous permettent de voir leur documentation sous la forme HTML (directement sur le site donc) ainsi que des informations sur ces modules, comme par exemple une note qui leur est attribuée par les autres personnes utilisant le CPAN.
Le méta-CPAN permet quant à lui d'obtenir des informations comme la compatibilité du module

### Comment choisir un module

Pour bien choisir un module, nous prenons généralement un module avec un nom le plus générique possible, se rapprochant de ce que nous cherchons. Par exemple, si vous cherchez un module pour faire du réseau (échange de données entre différents ordinateurs tout simplement), vous allez chercher dans meta-cpan « network ».

## Créer un module

todo

# Chaînes de caractères

Cette page est considérée comme une ébauche à compléter . Si vous possédez quelques connaissances sur le sujet, vous pouvez les partager en éditant dès à présent cette page (en cliquant sur le lien « »).
Ressources suggérées : Aucune (vous pouvez indiquer les ressources que vous suggérez qui pourraient aider d'autres personnes à compléter cette page dans le paramètre « ressources » du modèle engendrant ce cadre)
Le langage Perl permet de gérer les chaînes de caractères.
Comme il s'agit d'une langage ancien, il a d'abord été conçu pour gérer les anciens codages de textes (ASCII, iso-8859-x, etc.).
Le langage Perl s'adapte tout de même à son époque, et il est en particulier possible de traiter des textes Unicode. Si vous ne connaissez pas Unicode, vous pouvez le découvrir avec le livre À la découverte d'Unicode.
Des pages de manuels de Perl sont dédiées à l'Unicode, comme perlunicode ou perluniintro.

## Fonctions de manipulation des chaînes
### substr

    Extrait une sous-chaîne.

### length

    Calcule la longueur d'une chaîne.

### lc

    Transforme une chaîne en minuscules.

### uc

    Transforme une chaîne en majuscules.

### lcfirst

    Transforme le premier caractère d'une chaîne en minuscule.

### ucfirst

    Transforme le premier caractère d'une chaîne en majuscule.

### chop

    Supprime le dernier caractère d'une chaîne.
Il est utilisé surtout pour effacer les \n ("entrées" ou Carriage Return).

### chomp

    Permet de supprimer plusieurs caractères à la fin d'un chaîne.

### reverse

    Inverse l'ordre des caractères d'une chaîne.

# Expressions régulières
## Introduction

Les expressions régulières sont des outils de l'informatique théorique permettant de décrire les langages de manière formelle. Elles sont implémentées dans beaucoup de langages de programmation dont Perl qui les utilisent avec une syntaxe étendue (fonction, code dans l'expression régulière, ...).
Ce chapitre peut vous être utile peu importe quel langage vous avez l'habitude de manipuler ou que vous utiliserez à l'avenir. N'hésitez pas à lire ce chapitre en plusieurs fois pour apprécier toutes les subtilités et pour comprendre à quel point ceci fait partie intégrante du langage Perl et comment bien se servir de ces outils.

### Définition

Une expression régulière est une manière de manipuler du texte de façon concise et claire à l'aide de motifs. Les expressions régulières (ou « rationnelles », aussi appelées « regex » pour « regular expression ») sont issues des théories mathématiques sur les langages formels.

### Format

Tout d'abord, nous utilisons le symbole =~ pour utiliser des expressions régulières, ensuite nous avons toute une panoplie de fonctionnalités à appliquer sur un texte (recherche, remplacement…), avec des options disponibles. Pour cela, voici la syntaxe :
Pour rappel, ce qui est entre crochets n'est pas toujours obligatoire. Le remplacement de texte par exemple nécessitera de rechercher du texte (première zone de texte) puis de le remplacer par un autre texte (seconde zone de texte). Pour la recherche de texte, pas besoin d'indiquer la seconde zone.
À savoir : cet exemple utilise des slashs (/) cependant nous pouvons utiliser d'autres caractères, comme l'underscore, un point d'exclamation, ou encore des accolades par exemple. Ceci est pratique lorsque nous avons à chercher un motif contenant des slashs (pas besoin de le banaliser, c'est à dire rajouter un antislash « \ » devant le caractère).

### Exemple

Un exemple simple d'utilisation serait de chercher un mot dans un texte, fonctionnalité m (Match en anglais) :
Comme on peut s'y attendre, ce code va afficher « On a trouvé « fromage » dans le texte » puisque nous recherchons le mot « fromage » dans $texte. En fait, la fonction cherche à savoir si le texte correspond (match en anglais) au motif spécifié. Celui-ci ne contenant pas d'ancre de début ou fin de texte, peut correspondre avec une partie se trouvant au milieu du texte.

## Fonctionnalités

Les expressions rationnelles peuvent être analysées et testées via un débogueur en ligne comme https://regex101.com/.
Expressions rationnelles courantes :
| Caractère | Type | Explication |
| . | Point | N'importe quel caractère |
| [...] | crochets | classe de caractères : tous les caractères énumérés dans la classe, avec possibilité de plages dont les bornes sont séparées par "-". Ex : [0-9a-z] pour tout l'alphanumérique en minuscule, ou [0-Z] pour tous les caractères de la table Unicode entre "0" et "Z", c'est-à-dire l'alphanumérique majuscule plus ":;<=>?@". |
| [^...] | crochets et circonflexe | classe complémentée : tous les caractères sauf ceux énumérés. |
| [...[...]] | union | Union des deux ensembles |
| [...&&[...]] | intersection | Intersection des deux ensembles |
| ^ | circonflexe | Marque le début de la chaîne ou de la ligne. |
| $ | dollar | Marque la fin de la chaîne ou de la ligne. |
| | | barre verticale | Alternative - ou reconnaît l'un ou l'autre |
| (...) | parenthèses | groupe de capture : utilisé pour limiter la portée d'un masque ou de l'alternative, grouper un motif répété ou capturer une séquence |
| \n | référence | Même séquence que celle capturée précédemment par le nème groupe de capture |
| \g{n} | référence | Même séquence que celle capturée précédemment par le nème groupe de capture |
| (?P<nom>pattern) | Sous-motif nommé | Nomme le résultat d'un groupe de capture par un nom. |
| \g{nom} | référence | Même séquence que celle capturée précédemment par le groupe de capture nommé nom. |
| \k<nom> | référence | Même séquence que celle capturée précédemment par le groupe de capture nommé nom. |
Par défaut, les caractères et groupes ne sont pas répétés. Les quantificateurs permettent de spécifier le nombre de répétitions et sont spécifiés immédiatement après le caractère ou groupe concerné.
Quantificateurs :
| Caractère | Type | Explication |
| * | astérisque | 0, 1 ou plusieurs occurrences |
| + | plus | 1 ou plusieurs occurrences |
| ? | interrogation | 0 ou 1 occurrence |
| {...} | accolades | nombre de répétitions : spécifie le nombre de répétitions du motif précédent (minimum et maximum). Avec la présence de la virgule, quand le minimum est absent la valeur par défaut est zéro, quand le maximum est absent la valeur pas défaut est l'infini. Sans virgule (un seul nombre) il s'agit du nombre exact (minimum et maximum ont la même valeur). Exemples : a{2} deux occurrences de "a", a{1,10} (sans espace) entre une et dix, a{,10} jusqu'à 10 fois (de 0 à 10), a{3,} au moins 3 fois (de 3 à l'infini). |
Par défaut les quantificateurs ne recherchent pas forcément la plus longue séquence de répétition possible. Il est possible de les suffixer avec un caractère pour modifier leur comportement.
Modificateurs de quantificateurs :
| Caractère | Type | Explication |
| ? | réticent | Le quantificateur qui précède recherchera la plus petite séquence possible. |
| + | possessif | Le quantificateur qui précède recherchera la plus grande séquence possible. |
Remarques :
* Les caractères de début et fin de chaîne (^ et $) ne fonctionnent pas dans où ils ont un autre rôle.
* Les opérateurs * et + sont toujours avides, pour qu'ils laissent la priorité il faut leur apposer un ? à leur suite.
Classes de caractères POSIX :
| Classe | Signification |
| [[:alpha:]] | n'importe quelle lettre |
| [[:digit:]] | n'importe quel chiffre |
| [[:xdigit:]] | caractères hexadécimaux |
| [[:alnum:]] | n'importe quelle lettre ou chiffre |
| [[:space:]] | n'importe quel espace blanc |
| [[:punct:]] | n'importe quel signe de ponctuation |
| [[:lower:]] | n'importe quelle lettre en minuscule |
| [[:upper:]] | n'importe quelle lettre capitale |
| [[:blank:]] | espace ou tabulation |
| [[:graph:]] | caractères affichables et imprimables |
| [[:cntrl:]] | caractères d'échappement |
| [[:print:]] | caractères imprimables exceptés ceux de contrôle |
Expressions rationnelles Unicode :
| Expression | Signification |
| \\ | Antislash |
| \C | Caractère spécial C non interprété : [ ] { } ( ) ? * . : \ & - ^ $ |
| \Q...\E | Séquence littérale non interprétée |
| \0xxx | Caractère Unicode (1 à 3 chiffres octaux) |
| \a | Alarme (ASCII 07) |
| \A | Début de chaîne |
| \b | Caractère de début ou fin de mot |
| \B | Caractère qui n'est pas début ou fin de mot |
| \cX | Caractère de contrôle ASCII (X étant une lettre) |
| \d | Chiffre |
| \D | Non chiffre |
| \e | Escape (ASCII 1B) |
| \f | Form-feed (ASCII 0C) |
| \G | Fin de la correspondance précédente |
| \h | Espace blanc horizontal [ \t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000] |
| \H | Non espace blanc horizontal [^\h] |
| \n | Fin de ligne |
| \pL, \p{L}, \p{Letter} | Lettre (dans tout langage) |
| \r | Retour charriot |
| \R | Retour à la ligne, équivaut à \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029] |
| \s | Caractères espace [ \t\n\x0B\f\r] |
| \S | Non caractères espace [^\s] |
| \t | Tabulation |
| \uxxxx | Caractère Unicode (4 chiffres hexadécimaux) |
| \v | Espace blanc vertical [\n\x0B\f\r\x85\u2028\u2029] |
| \V | Non espace blanc vertical [^\v] |
| \w | Caractère alphanumérique : lettre, chiffre ou underscore |
| \W | Caractère qui n'est pas lettre, chiffre ou underscore |
| \xxx | Caractère Unicode (2 chiffres hexadécimaux) |
| \x{xx...x} | Caractère Unicode (chiffres hexadécimaux) |
| \X | Caractère Unicode du groupe de graphèmes étendu |
| \z | Fin de chaîne |
Constructeurs spéciaux : Ces fonctions précèdent l'expression à laquelle elles s'appliquent, et le tout doit être placé entre parenthèses.
* ?: : groupe non capturant. Ignorer le groupe de capture lors de la numérotation des backreferences. Exemple : ((?:sous-chaine_non_renvoyée|autre).*).
    La présence d'un groupe capturant peut engendrer une allocation mémoire supplémentaire. Si une expression régulière particulièrement complexe provoque une erreur de mémoire, essayez de remplacer les groupes capturant non référencés et inutilisés par des groupes non-capturant en ajoutant ?: juste après la parenthèse ouvrante, et en décalant les numéros des groupes référencés.
* ?> : groupe non capturant indépendant.
* ?<= : positive lookbehind, vérifier (sans consommer) que ce qui précède correspond au motif spécifié. Exemple :
    Chercher une lettre u précédée d'une lettre q : (?<=q)u
* ?<! : negative lookbehind, vérifier (sans consommer) que ce qui précède ne correspond pas au motif spécifié.
* ?= : positive lookahead, vérifier (sans consommer) que ce qui suit correspond au motif spécifié.
* ?! : negative lookahead, vérifier (sans consommer) que ce qui suit ne correspond pas au motif spécifié. Exemples :
    Chercher une lettre q non suivie d'une lettre u : q(?!u)
    ((?!sous-chaine_exclue).)
    <(?!body).*> : pour avoir toutes les balises HTML sauf "body".
    début((?!mot_exclu).)*fin : pour rechercher tout ce qui ne contient pas un mot entre deux autres.
    (?!000|666) : pour exclure 000 et 666.
Options :
Les options d'interprétation sont en général spécifiées à part. Mais certaines API ne permettent pas de les spécifier. Il est possible d'insérer ces options dans l'expression régulière.
    (?optionsactivées-optionsdésactivées)
Exemples :
* Chercher un mot composé de voyelles sans tenir compte de la casse :
    (?i)[AEIOUY]+
* Chercher un mot composé de voyelles en tenant compte de la casse, ici en majuscules :
    (?-i)[AEIOUY]+
Les options s'appliquent à toute l'expression quelle que soit leur position dans l'expression.
Nous allons faire un tour des fonctionnalités (que j'appellerai également modes) les plus utilisés.

### recherche : m

Pour effectuer des recherches dans une chaîne de caractère, nous utilisons la fonctionnalité m. C'est le mode par défaut, nous n'avons pas besoin de l'écrire.

### remplacement : s

Le mode s permet d'effectuer un remplacement (aussi appelé substitution) dans une chaîne. Ici, nous avons besoin d'utiliser les deux zones de textes, de cette manière : s/texte à changer/nouveau texte/ .

#### exemple de substitution
### constructeurs spéciaux :
#### ?= préviseur positif (positive lookahead)
#### ?> constructeur tête de mule !

Attrape la chaîne correspondante maximale où il est ancré, et refuse de faire un pas en arrière
( pas de backtracking pour trouver toutes les sous-chaînes ).
Sert à l'optimisation :
Pour 2 000 "a", on attend 2 003 000 recherches (sans ?>) contre 2 000 seulement (avec ?>).

## Correspondances

Lors d'une recherche de motif, nous pouvons utiliser des caractères spéciaux (parfois appelés « méta-caractères ») pour rechercher un type de caractère (et non un caractère explicitement).

### caractères et expressions de correspondance
#### caractère quelconque : .

Le point « . » correspond à un caractère quelconque. Lors d'une recherche, nous pouvons l'utiliser pour indiquer n'importe quel caractère, excepté le retour à la ligne (\n).

##### exemple utilisation du point
#### caractère alphabétique : [[:alpha:]]

Pour rechercher un caractère alphabétique on utilise: [[:alpha:]] ou éventuellement [a-zA-Z].

#### caractère numérique : \d et [[:digit:]]

Nous avons deux possibilités pour rechercher un caractère numérique : [[:digit:]] et \d. Pour chercher un caractère qui n'est pas un chiffre : \D.

#### caractère hexadécimal : [[:xdigit:]]

Cela correspond à tout caractère hexadécimal, c'est à dire tous les caractères numériques (de 0 à 9) et les lettres de A à F.

#### caractère alphanumérique : [[:alnum:]] et \w

Les caractères alphanumériques correspondent à l'ensemble des caractères numériques (0,1,2…) et aux lettres. La classe \w reconnaît, en plus de [[:alnum:]], le caractère «_». Pour chercher un caractère qui n'est pas un nombre ou une lettre ou «_» : \W.

#### caractère d'espacement simple : [[:blank:]]

Un espacement correspond à un espace, une tabulation.

#### caractère d'espacement quelconque : \s et [[:space:]]

On cherche ici un espacement tel qu'une tabulation, un espace, un saut de ligne ou de page. Pour chercher un caractère qui n'est pas un espacement : \S.

#### correspondances partielles :

Nous cherchons une correspondance avec uniquement une partie des caractères, nous utilisons alors. Nous pouvons choisir d'énumérer explicitement tous les caractères dont nous souhaitons vérifier la correspondance en les écrivant entre ces crochets. Un moyen plus répandu (lorsque cela est possible) est d'utiliser une suite de caractères, par exemple de « a » à « z » de cette manière : [a-z]. Pour correspondre avec l'inverse de ce qu'on note entre crochets, il suffit de mettre en première lettre « ^ ». Ainsi, la recherche inverse de l'exemple précédent devient : [^a-z].

##### exemple de correspondance partielle

Cherchons à faire correspondre uniquement les caractères de « a » à « e » en minuscule, de « G » à « L » en majuscule et les chiffres de « 0 » à « 5 » et les chiffres 7 et 9.
crochets
crochets [^…]

## Options
### ignorer la casse

La « casse » désigne en informatique la différence entre minuscule et majuscule. Si on choisi d'ignorer la casse, alors nous recherchons un motif sans distinction avec ou sans majuscules. Pour cela nous avons l'option i.

### recherche en mode multi-ligne

Nous recherchons un motif en traitant la chaîne en tant que constituée de plusieurs lignes. Concrètement, nous voulons que ^ et $ ne correspondent pas seulement au début et fin de la chaîne, mais aussi au début et fin de chaque ligne. Pour cela, nous avons l'option m.

#### exemple de recherche en mode multi-ligne
### faire correspondre . à un saut de ligne

Lorsque nous faisons des recherches sur plusieurs lignes, on souhaiterait pouvoir considérer le saut de ligne comme un caractère quelconque (comme tous les autres). Nous pouvons faire cela avec l'option s.

#### exemple utilisation de l'option s

Nous reprenons l'exemple précédent avec la recherche sur plusieurs lignes, désormais nous n'avons pas à écrire explicitement le saut de ligne, nous pouvons utiliser le métacaractère ..

### permettre d'écrire l'expression régulière avec des commentaires

L'option « x » permet d'écrire une expression régulière sans tenir compte des caractères d'espacement. Ainsi, on peut espacer ses expressions avec des retours à la ligne si on veut, sans que cela n'influe sur votre expression. Si vous souhaitez rechercher une chaîne de caractères avec des espaces à certains endroits, il faudra l'indiquer explicitement dans votre expression avec la recherche d'un caractère d'espacement (voir plus haut).

### appliquer un changement plusieurs fois dans la chaîne

Lors de la substitution de texte, nous souhaiterions par exemple changer tous les caractères « a » par « b ». Par défaut, seule la première occurrence de « a » serait modifiée. Pour changer ce comportement et changer tous les « a », nous utilisons l'option g.

### cumuler les options

Nous pouvons additionner les options en les écrivant à la suite (/ig par exemple). Nous avons déjà vu un exemple plus haut en cumulant les options m (recherche de motif sur plusieurs lignes) et s (retour chariot inclut dans les caractères auxquels le point correspond). Autre exemple, nous pouvons effectuer une substitution plusieurs fois par ligne en ignorant la casse du motif à remplacer.

## Ancres

Les ancres correspondent au placement du texte à rechercher.

### rechercher en début de chaîne : ^ et \A

On utilise pour cela le caractère ^ ou \A qui correspond au début de la chaîne. Avec l'option /m le caractère ^ correspond également à tout début de ligne (voir plus haut).

#### exemple de recherche en début de chaîne

^ début de ligne

### rechercher en fin de chaîne : $, \Z et \z

$ est l'analogue de ^ mais en fin de chaîne (ou de ligne aussi avec option m). \z est l'analogue de A en fin de chaîne, donc non affecté par l'option m. \Z est comme \z mais peut correspondre aussi à un retour à la ligne en fin de chaîne.

#### exemple de recherche en fin de chaîne

$ fin de ligne

## Quantification

Nous allons aborder maintenant la partie concernant l'identification d'un motif se répétant.

#### exemple d'introduction au quantifications

Avant de commencer, il faut se confronter au problème. Nous avons une chaîne de caractères, et nous souhaitons savoir si elle contient deux fois le caractère « a ». Vu l'étendue des connaissances acquises jusque-là, nous devrions résoudre le problème comme suit :
Maintenant, on souhaite savoir si la chaîne de caractères contient deux fois le caractère « a » (jusque-là, le problème reste identique) sauf que ces deux caractères peuvent être séparés par un caractère quelconque (ou pas). Là encore, vu l'étendue des connaissances acquises actuellement, cela donnerait :
Nous résolvons le problème ici assez facilement, mais qu'en est-il si nous cherchons deux fois le caractère « a » avec un nombre quelconque de caractères séparateurs ? Impossible actuellement.

### Quantifier par un nombre :

Nous avons une chaîne de caractères, et nous recherchons un motif quelconque se répétant un certain nombre de fois. Nous pouvons expliciter ce nombre de fois, ou simplement donner une tranche :

#### exemples avec :

Ligne 2 : il y a correspondance car nous avons précisément deux caractères séparant les deux lettres « c ». Ligne 3 : il y a correspondance là aussi, car il y a un nombre compris entre 1 et 3 caractères entre les deux lettres « c ». Attention : ligne 4 ne correspond pas car il faudrait qu'il y ait 2 lettres « u » consécutives et non toute la chaîne « cou » ! Nous verrons plus tard comment procéder pour faire cela. Enfin, ligne 5 correspond car on cherche « au moins » un caractère entre deux « c ».

### Entre 0 ou 1 occurrence : ?

Il est possible que le caractère (ou plus généralement le motif) soit présent ou non. On utilise pour cela le quantificateur ?.

### Entre 0 ou un nombre non déterminé d'occurrences : *

Quand il peut y avoir 0 ou une infinité d'occurrences d'un motif, on utilise le caractère spécial * .

## Capturer du texte

La capture du texte (d'un certain motif) permet de réutiliser ce texte pour le replacer (en le modifiant éventuellement).

### Simple capture de texte :

Nous souhaitons prendre une partie du texte pour le réutiliser. Lorsque vous capturez du texte, les variables $1, $2 … sont mises à jour avec la capture que vous venez de faire entre parenthèses. Ainsi, le premier groupe capturé par pourra être réutilisé dans votre code via la variable $1, le second avec la variable $2 et ainsi de suite jusqu'à $9.

### Captures avides ou non avides

Le plus simple pour comprendre ce qu'est une capture avide est de prendre un exemple.

#### capture avide
##### exemple 1 de capture avide

Soit la capture « (c+) » qui va prendre une fois ou un nombre non limité de fois la lettre « c ».
Si vous exécutez ce code, vous verrez affiché « cccccc » et non pas un seul « c ». Cela est dû à l'avidité (en anglais greedy) des opérateurs.

##### exemple 2 de capture avide

Un autre exemple, un peu plus complexe, pour bien comprendre le phénomène, qui peut s'avérer gênant : nous avons une chaîne de caractères avec des champs délimités par des doubles points « : » :
Ici, nous affichons le nom, le prénom et l'âge, car nous prenons la chaîne la plus longue possible correspondant à notre expression. C'est à dire, la chaîne la plus longue se terminant par un double point.

#### capture non avide

Maintenant, ce qu'on voudrait c'est de ne prendre que la plus petite partie possible qui correspond à notre expression régulière. La solution est de remplacer chaque quantificateur par sa version non avide :
* , +, ?, et deviennent respectivement *?, +?, ?? et?.

# Les coulisses des regex
## @+ et @- les @rchiveurs de regex

@+ matrice des fins des chaînes trouvées ($+[0] fin globale, $+[1] fin de $1 …)
@- matrice des débuts des chaînes
Les items de @+ ne se notent pas @+[0], @+[1] … mais $+[0], $+[1] … car ce sont des scalaires.

# Orienté Objet
## Introduction

Cette page sera écrite en deux parties distinctes : la définition de la programmation orientée objet en faisant abstraction d'un langage en particulier, puis comment l'utiliser dans le langage étudié.
Gardez à l'esprit que le concept de programmation orientée objet est simple, il y a juste quelques mots de jargon à connaître.

### Ce qu'est la programmation orientée objet

La programmation orientée objet est une manière de concevoir une application. La page wikipedia à ce sujet est bien faite, mais faisons un petit résumé pratique (et plus clair).
La POO se base sur quelques notions assez simples (rappelons que le but est de simplifier la programmation).

#### Les objets et leur classe

Un objet est un ensemble d'attributs (variables) et de méthodes (fonctions). Une voiture par exemple pourrait se représenter par un objet « Voiture ». Elle est composée de quatre roues, un volant, quatre sièges… qui représentent autant d'attributs de l'objet. La voiture peut également se démarrer, rouler, tourner, s'arrêter… qui représentent les méthodes possibles pour cet objet.
Dans la plupart des langages, pour créer un objet et le définir, nous créons une classe (un fichier avec les différents attributs et méthodes de l'objet). À partir de cette classe, nous pouvons créer des instances. Ainsi, nous pouvons avoir autant de voitures que nous le souhaitons, qui possèdent toutes les mêmes attributs (pas forcément de même valeur cependant) et les mêmes méthodes, à partir de la classe voiture. Exemple : la classe voiture possède un attribut « couleur » et des méthodes (rouler, tourner…), nous créons deux instances de la classe voiture, une avec l'attribut « couleur » à « rouge » et l'autre à « bleue ». Les voitures sont indépendantes.

#### Le typage et le polymorphisme

Chaque objet est un type différent (le type est le nom de sa classe). Il définit ses propres attributs et ses méthodes, et il est utile d'un point de vue sémantique dans notre code. Prenons par exemple la gestion d'un parking, on va faire entrer des « Voitures » dans ce parking, pas des entiers ou une chaîne de caractères. C'est donc une structure de données qui a un but sémantique.

#### Héritage et redéfinition

Pour simplifier l'écriture de code (et en écrire moins), on a créé le principe d'héritage. Prenons un exemple simple : nous souhaitons gérer un jeu de courses de voitures. Nous possédons une trentaines de modèles de voitures différentes (quelques particularités qui changent), cependant elles ont toutes quatre roues, des portières etc. Pour simplifier l'écriture du code, nous allons définir ce qu'est une voiture, et dire que les différents modèles « héritent » de la classe « voiture ». Ainsi, tous les modèles possèdent de base les attributs qu'ils ont en commun, sans avoir à le dire explicitement dans chaque classe. On vient donc de factoriser grandement notre code.

## Perl et la POO

Perl a connu plusieurs implémentations de programmation orientée objet via différents modules. Afin d'harmoniser les pratiques, Perl6 reprend le concept de POO dans sa syntaxe de base, et ceci a été repris dans Perl5 par le module Moose. Nous allons voir comment programmer en orienté objet avec cette bibliothèque, qui s'avère de nos jours être la bonne manière de coder en POO en Perl.

### Bases de POO en Perl
#### Créer une instance : new

Chaque package possède implicitement une méthode particulière (souvent appelée « new ») pour créer une instance de la classe. Nous appelons les méthodes d'un objet via l'opérateur « -> ».
$objet est maintenant une référence à un objet « Voiture ».

#### Créer et appeler une méthode : sub et ->

Une méthode est une simple fonction comme nous avons déjà vu dans un chapitre précédent. Le premier paramètre est une référence à l'objet courant. Cette méthode est définie dans un « package », qui sera notre classe. Nous verrons plus loin comment créer une classe, pour voir directement la bonne manière de faire (via Moose).
Comme nous l'avons vu précédemment avec « new », pour appeler une méthode il suffit d'utiliser l'opérateur « -> ».
À remarquer : au début on utilise l'opérateur « -> » sur le package directement pour créer l'instance, après on l'utilise sur l'objet référençant l'instance pour faire appel aux méthodes liées à un objet en particulier (que l'on nomme méthodes d'instance).

### POO via Moose

Nous arrivons à la partie la plus intéressante. Jusque-là tout était peut-être un peu flou, mais cela va s'éclaircir !

#### Créer une classe

Une classe se définit par un package, l'utilisation de Moose et se termine par « 1; » tout à la fin du fichier.
Difficile de faire plus simple non ? Cette classe ne contient rien de bien utile pour le moment, on ne peut que créer une instance de l'objet comme vu précédemment.

#### Les attributs
##### Bases : has is isa required

Un attribut est déclaré avec le mot clé has. On doit lui passer au moins un paramètre : l'option « is » qui définit si l'attribut est en lecture seule (ro pour read-only) ou s'il est en lecture et écriture (rw pour read-write).
Les attributs peuvent avoir un type précis, qui se trouve dans [liste]. Nous forçons à vérifier ce type avec l'option isa.
Nous pouvons même créer de nouveaux types mais cela va au delà du but de ce livre, veuillez vous référer à la documentation officielle du module MooseUtilTypeConstraint.
Nous pouvons décider qu'une option est obligatoire.
Il y a d'autres options disponibles dont de très intéressantes et puissantes à découvrir dans la documentation du module, que j'encourage vivement à aller voir pour les anglophones.

##### Déclarer plusieurs attributs directement

Petite astuce pour gagner du temps, déclarer plusieurs attributs avec les mêmes options.

##### Créer l'instance en modifiant la valeur des attributs

On peut choisir de modifier la valeur d'un attribut dès la création de l'instance de la classe.

##### Récupérer et modifier la valeur d'un attribut

Pour récupérer ou modifier un attribut, il faut passer par des fonctions nommées accesseurs. Pour récupérer la valeur d'un attribut il suffit d'écrire $objet->nom_attribut et pour la modifier $objet->nom_attribut("nouvelle valeur").

##### Modifier les noms des accesseurs

Il est possible de modifier les fonctions d'accès et de modification des attributs. Cela se fait grâce aux options reader et writer de la création d'un attribut.
Une convention veut que nous nous précédions le nom de l'accesseur par un underscore ( _ ) lorsque nous ne voulons pas que les classes filles l'utilisent. Rien n'empêche en pratique leur utilisation, mais cela est à utiliser à vos risques.

##### Déclencheur sur la modification d'un attribut : trigger

Lors la modification d'un attribut on veut avoir une fonction qui soit appelée.
Soit le fichier Personnage.pm :
Soit le fichier Jeu.pl :

##### Références faibles : weak_ref

Tout d'abord, petit point sur la façon dont Perl gère la mémoire.
En Perl, nous ne manipulons pas directement la mémoire de l'ordinateur, la gestion est déléguée directement à Perl. Quand on n'utilise plus une variable, ou un objet, il faut « libérer » la zone mémoire qu'elle occupe. Pour trouver ce qu'il faut libérer, on utilise un ramasse-miettes (Garbage Collector). Il y a différentes manières d'implémenter un ramasse-miettes, celle utilisée par Perl est le comptage de références.
Le principe est assez simple : pour chaque variable on va compter le nombre de fois qu'on a une référence qui pointe dessus, une fois qu'on n'en a plus, on ne peut plus accéder à cette zone mémoire. Par conséquent, on peut libérer la mémoire puisque la variable n’est de toutes manières plus utilisable. Pour plus d'informations, je conseille d'aller voir la page sur les ramasse-miettes sur wikipedia.
Soit le module Personnage tel que :
Soit le code utilisant ce module :

#### Héritage : extends

Comme nous avons vu en introduction de ce chapitre, l'héritage permet de créer des classes décrivant toujours un objet plus précis. Par exemple, pour un jeu vidéo on fait une classe "Personnage" puis une classe "Magicien". Un magicien est un personnage. Il hérite donc de toutes ses propriétés et en rajoute potentiellement.
Soit le module Personnage tel que :
Maintenant on veut créer le magicien qui, en plus d'avoir un nom, pourra lancer une boule de feu. Soit le module Magicien :
Maintenant on essaie notre classe :
Perl permet l'héritage multiple, ce qui veut dire qu'une classe peut hériter de plusieurs autres classes, voici la syntaxe :

##### Modifier une méthode héritée (surcharge)

Lors d'un héritage, on souhaite parfois changer une méthode dont on hérite, cela s'appelle une surcharge. Pour cela nous n'avons qu'à recréer une méthode de même nom qui remplacera l'ancienne.

##### Modifier un attribut hérité : +

On souhaite parfois changer une option de l'attribut, comme par exemple rendre un attribut non modifiable (ro) ou donner une valeur par défaut à un attribut, pour cela on peut modifier la définition de l'attribut. Cela se fait simplement en rajoutant un "+" devant le nom de l'attribut dans notre classe fille (celle qui hérite).
Attention cependant, il est déconseillé de redéfinir un attribut juste pour changer sa valeur par défaut, on préfèrera donner une valeur par défaut à un attribut dans le constructeur de la classe.

#### Les rôles : Moose::Role with requires

Un rôle n'est pas à proprement parler une classe, mais plutôt une alternative à la hiérarchie imposée par la programmation orientée objet. Si nous reprenons des exemples déjà vus : un magicien est un personnage. Un magicien peut aussi être un guérisseur (qui soigne les autres personnages) mais ce n'est pas nécessairement le cas. On peut dire qu'il remplit la fonction de guérisseur, il a ce rôle.
Un rôle est défini comme une classe, avec éventuellement des attributs et des méthodes et utilise Moose::Role en lieu et place de Moose. Ce que nous allons faire généralement avec les rôles c'est de les utiliser pour indiquer des fonctions qui doivent apparaître dans la classe qui a ce rôle. Pour cela nous utilisons le mot clé "requires".
Soit le rôle Guerisseur :
Notre classe Magicien :
Maintenant faisons un essai sur notre code :
Un rôle ne peut pas être instancié. Si on créer des méthodes ou qu'on défini des attributs dans le rôle, alors les classes qui ont ce rôle auront aussi ces attributs et ces méthodes, comme en cas d'héritage.

# Ressources
## Liens web

* Apache/CGI#Perl
* Documentation Perl en français
* Créer de la documentation avec POD
* PerlFR
* Guide Perl - Débuter et progresser en Perl (Sylvain Lhullier)
* Articles des mongueurs
* Sources DocBook

## Livres autour de Perl

* Perl - Pocket Reference, de Johan Vromans, O'Reilly
* Perl Moderne, de Sébastien Aperghis-Tramoni, Philippe Bruhat, Damien Krotkine, Jérôme Quelin, Pearson
* ↑ https://unicode-table.com/fr/
* ↑ https://docstore.mik.ua/orelly/webprog/pcook/ch13_05.htm
* ↑ https://www.regular-expressions.info/posixbrackets.html
* ↑ https://www.regular-expressions.info/unicode.html
* ↑ https://www.regextester.com/15
* ↑ Jan Goyvaerts, Steven Levithan, Regular Expressions Cookbook, O'Reilly Media, Inc., 22 mai 2009 (lire en ligne)
* ↑ Les options sont appelées modificateurs (modifiers en anglais), voir https://www.regular-expressions.info/modifiers.html