Une des limitations de perl4 venait du fait qu'il était impossible de créer et de manipuler des structures de données plus évoluées que de simples tableaux sans passer par des astuces plus ou moins efficaces.
Une des grandes innovations de perl5 a été l'introduction des références, qui permettent de travailler sur des structures de données plus complexes.
Une référence est un scalaire qui pointe sur une structure de données (scalaire, tableau, tableau associatif, fonction).
Du fait de sa nature scalaire, il est possible de construire des tableaux de références. Et si ces références pointent sur des tableaux par exemple, on obtient ainsi des tableaux de tableaux, i.e. un tableau à deux dimensions.
perl garde trace du nombre de références sur un objet. Une fois que celui-ci atteint 0, l'objet est détruit et la mémoire libérée.
Soit @liste un tableau. Alors on peut obtenir sa référence
avec l'expression suivante : $
ref =
@liste
Si on exécute la ligne print $
ref;, on obtient quelque
chose du type :
ARRAY(0x91a9c).
Il y a deux manières d'utiliser ensuite cette référence. On peut la déréférencer pour la manipuler comme un tableau normal :
@new = @$ref; print $new[0];
ou bien on peut accéder directement aux données en remplaçant le nom du tableau par la référence :
print $$ref[0]; # ou bien print $ref->[0];
On peut donc ainsi construire facilement des tableaux à plusieurs dimensions :
print $table[0]->[2]->[4];
Les flèches étant optionnelles entre les crochets ou les accolades, on peut également l'écrire :
print $table[0][2][4];
Ces exemples s'appliquent également aux références sur des tableaux associatifs ou des scalaires.
Nous avons vu jusqu'ici comment créer une référence à partir d'une variable existante. Mais il est également possible de créer des références sur des structures anonymes en vue d'obtenir des structures de données plus complexes.
Voilà par exemple comment créer un tableau de tableaux :
@liste = (); for $i ('A'..'z') { push(@liste, [ $i, ord($i) ]); } print @{$liste[0]}; # -> affichage de ('A', 65) sous la forme A65 print ${$liste[0]}[0]; # -> affichage de 'A' sous la forme A # ou bien @paire = @{$liste[0]}; print $paire[0]; # -> affichage de 'A' sous la forme A
Ceci va créer un tableau à deux dimensions (ou plutôt un tableau de tableaux).
La notation [] renvoie une référence sur un tableau composé des éléments que les crochets renferment.
De la même manière, la notation {}
renverra une
référence sur un tableau associatif composé des éléments
encadrés par les accolades :
@liste = (); for $i ('A'..'z') { push(@liste, { "caractere" => $i, "valeur" => ord($i) } ); } print %{$liste[0]}; # -> affichage du tableau associatif ("caractere" => "A", # "valeur" => 65) # sous la forme caractereAvaleur65 print ${$liste[0]}{"caractere"}; # -> "A" # ou bien %paire = %{$liste[0]}; print $paire{"caractere"}; # -> "A"
On peut ainsi imbriquer plusieurs niveaux de références pour créer des structures de données complexes (mais attention à la mémoire utilisée !).
On peut de la même manière que pour les tableaux créer des références sur des fonctions de deux façons différentes.
À partir d'une fonction déjà existante :
sub fonc { ...; } $ref = \&fonc;
ou bien en créant une référence sur une fonction anonyme :
$ref = sub { print "hello world !\n";};
On peut ensuite appeler directement :
&$ref;
L'introduction des références a permis d'introduire également les concepts de la programmation orientée objets. Pour obtenir une documentation plus complète, se référer aux pages de manuel [3] perlobj et perlbot. Un tutorial est également accessible par la commande perldoc perltoot.
Attention : cette section ne constitue pas une introduction à la programmation objet. Il est considéré que le lecteur aura déjà été sensibilisé à certains de ses concepts.
Voici les trois grands principes d'implémentation des objets en perl5.
En général, on utilise une référence sur un tableau associatif, qui contient les noms et les valeurs des variables d'instance.
Supposons que la classe Window soit définie. Alors on crée un objet appartenant à cette classe en appelant son constructeur :
$fenetre = new Window "Une fenetre"; # ou dans un autre style $fenetre = Window->new("Une fenetre");
Si Window a une méthode expose définie, on peut l'appeler ainsi :
expose $fenetre; # ou bien $fenetre->expose;
Voici un exemple de déclaration de la classe Window:
package Window; # La methode de creation. Elle est appelee avec le nom de la # classe (ie du paquetage) comme premier parametre. On peut passer # d'autres parametres par la suite sub new { # On recupere les arguments my($classe, $parametre) = @_; # L'objet qui sera retourne est ici (et c'est generalement le cas) # une reference sur un tableau associatif. Les variables # d'instance de l'objet seront donc les valeurs de ce tableau. my $self = {}; # On signale a $self qu'il depend du paquetage Window # (ie que sa classe est Window) bless $self; # Diverses initalisations $self->initialize($parametre); # On retourne $self return $self; } # Methode d'initalisation. # Le premier parametre est l'objet lui-meme. sub initialize { my($self, $parametre) = @_; $self->{'nom'} = $parametre || "Anonyme"; } # Autre methode. sub expose { my $self = shift; print "La fenetre ``, $self->{'parametre'}, " a recu un evenement expose.\n"; }