
| auteur : Djibril |
Les références Perl sont des variables qui permettent de référencer d'autres variables, tableaux, hashs, fonctions ou handles. La notion de référence peut être vue comme les pointeurs en C. Mais pas de panique :-(, c'est beaucoup plus simple que ce que vous croyez !
Vous allez me dire, oui, c'est bien beau, mais à quoi ça sert? Voici donc un exemple …
my @tab1 = (1, 2, 3);
my @tab2 = ('a', 'b', 'c');
&affiche(@tab1, @tab2);
sub affiche{
my (@recup1, @recup2) = @_;
print "voici votre tableau tab1 recupere dans ma fonction : @recup1\n";
print "voici votre tableau tab2 recupere dans ma fonction : @recup2\n";
}
resultat :
voici votre tableau tab1 recupere dans ma fonction : 1 2 3 a b c
voici votre tableau tab2 recupere dans ma fonction : |
bizarre le résultat non ??!! Dans notre exemple, deux tableaux @tab1 et @tab2 sont donnés en argument à notre fonction qui a pour unique but de les réafficher. Bah … vous remarquerez qu'il n'arrive pas à distinguer vos tableaux et à les récupérer correctement.
Il en aurait été de même avec des hashs.
Petite explication :
@_ récupère une liste des données (@tab1 et @tab2 concaténés). De ce fait, toutes les données récupérées se retrouvent dans @recup1, @recup2 reste vide. Comment doit-on faire pour que @recup1 et @recup2 soient corrects ?? Facile !!! Vous avez trouvé … les références !!! On passera en argument à la fonction les références de nos tableaux. !
|
| auteur : Djibril |
Nous avons bien compris avec l'exemple ci-dessus l'utilité des références. La question est maintenant de savoir comment faire pour désigner (créer une référence) un tableau, un hash etc. Rien de plus simple, il suffit juste de placer un back slash ("\") devant la variable à référencer. Ainsi, la référence $ref_tab de notre tableau @tab s'écrit
Exemples :
my $ref_tableau = \@mon_tableau;
my $ref_hash = \%mon_hash;
my $ref_fonction = \&ma_fonction;
my $ref_handle = \*FILE; |
Voilà, c'est aussi simple que ça. Par curiosité, essayez cet exemple : my @mon_tableau = (1,2,3);
my $ref_tab = \@mon_tableau;
print $ref_tab; |
Vous obtenez ce genre de résultat : ARRAY(0x225da0).
C'est l'adresse, la référence du tableau @mon_tableau. D'ailleurs, aussi doué que vous êtes, vous avez déjà dû rencontrer des erreurs avec ce genre de caractère!! Généralement, sans le savoir, c'est dû au fait qu'on pense travailler sur un tableau ou une valeur de ce dernier alors que l'on travaille sur sa référence. Sinon, il existe une autre façon de créer des références, qu'on appelle références anonymes, voir ci-dessous.
|
| auteur : Djibril |
Excusez mon vocabulaire, mais c'est une façon un peu tordue de créer une référence! En fait, on crée une référence sur une variable n'existant pas au préalable, ne possédant pas de nom. Je sais, ce n'est pas clair…. Ce sont des références sur des structures anonymes en vue d'obtenir des structures de données plus complexes. Un petit exemple vous éclaira, du moins je l'espère .. my $ref_tab = [1,2,3];
my $ref_hash = {"cle1" => "valeur1",
"cle2" => "valeur2"};
print $ref_tab;
print $ref_hash; |
Il vous affichera deux adresses. Et oui, c'est tordu comme raisonnement! La première pour le tableau (1,2,3) sans nom, la deuxième pour le hash ("cle1" => "valeur1", "cle2" => "valeur2") sans nom.
Vous remarquez les couleurs rouges pour que vous puissiez prêter attention à la façon d'écrire les références anonymes.
Petit résumé : un tableau s'écrit (1,2,3), une référence anonyme à un tableau [1,2,3].
Bon, c'est bien tout ce blabla, mais comment les utiliser ? On y arrive, on y arrive, allez voir ci-dessous (déférencement).
|
| auteurs : Djibril, Stoyak |
Ah enfin!!! Après toutes ces explications, vous allez enfin savoir utiliser ces fameuses références!! Tout d'abord, sachez qu'il existe deux façons de les utiliser (eh oui, c'est Perl, avec sa grande capacité à pouvoir écrire du code de différentes façons :-) ): 1) Première façon @{$ref_tableau} est identique à @tableau. ${$ref_tableau}[0] est identique à $tableau[0] %{$ref_hash} est identique à %hash ${$ref_hash}{"cle1"} est identique à $hash{"cle1"} Voici encore plus simple si vous voulez, mais plus bizarre quand on tombe dessus pour la première fois. Vous pouvez omettre les accolades si $ref a été déclaré : my $ref = \@tableau; @{$ref_tableau} est identique à @$ref_tableau. ${$ref_tableau}[0] est identique à $$ref_tableau[0] %{$ref_hash} est identique à %$ref_hash ${$ref_hash}{"cle1"} est identique à $$ref_hash{"cle1"} Résumé: @{$ref_tableau} est identique à @$ref_tableau, lui-même identique à @tableau ! En d'autres termes, un tableau est identique au tableau de sa référence ! C'est clair, non ?!!
- $ref=\@tab => création d'une référence, c'est le référencement
- @{$ref} => c'est le déférencement.
Exemple :
# declaration de mon tableau
my @mon_tableau = (1,2,3);
# declaration de la reference de mon tableau
my $ref_tab = \@mon_tableau;
print @{$ref_tab}; #ou print @$ref_tab;
et vous obtiendrez : 123 |
En résumé, il faut juste mettre {$ref} à l'endroit où on met d'habitude le nom du tableau ou d'un hash.
2) Deuxième façon
C'est une écriture simplifiée (ressemblant à l'écriture objet pour les connaisseurs). Cette méthode s'utilise surtout lorsque l'on travaille sur un élément de tableau et de hash. Exemple : mon tableau @tableau = (1,2,3);
sa référence $ref_tableau = \@tableau;
mon hash %hash = ("cle1" => "valeur1", "cle2" => "valeur2");
sa référence $ref_hash = \%hash; |
$ref_tableau->[0] est identique à ${$ref_tableau}[0] identique à $tableau[0] égal à la valeur 1 $ref_hash->{"cle1"} est identique à ${$ref_hash}{"cle1"} identique à $hash{"cle1"} égal à la valeur valeur1
Voilà, est ce compliqué??
Va falloir relire la doc plusieurs fois au début!! C'est normal!!
Bon pour la route, reprenons notre tout premier exemple (dans la section Qu'est ce qu'une référence, à quoi ça sert?) : my @tab1 = (1, 2, 3);
my @tab2 = ('a', 'b', 'c');
#on donne en argument à la fonction affiche les références à nos tableaux.
&affiche(\@tab1, \@tab2);
sub affiche{
#on recupere les references
my ($ref1, $ref2) = @_;
#affichage
print "voici votre tableau tab1 recupere dans ma fonction : @{$ref1}\n";
print "voici votre tableau tab2 recupere dans ma fonction : @{$ref2}\n";
}
resultat :
voici votre tableau tab1 recupere dans ma fonction : 1 2 3
voici votre tableau tab2 recupere dans ma fonction : a b c
Magique, non ?!! |
Attention!! Sachez tout de même qu'après l'appel de votre fonction, si celle-ci doit traiter et modifier le tableau, que le tableau d'origine sera modifié, lui aussi! Exemple : my @tab1 = (1, 2, 3);
my @tab2 = ('a', 'b', 'c');
#on donne en argument à la fonction affiche les références à nos tableaux.
&affiche(\@tab1, \@tab2);
print "voici votre tableau tab1 recupere dans ma fonction : @tab1\n";
print "voici votre tableau tab2 recupere dans ma fonction : @tab2\n";
sub affiche{
#on recupere les références
my ($ref1, $ref2) = @_;
push (@{$ref1}, "dudu");
push (@{$ref2}, "dudu");
}
resultat :
voici votre tableau tab1 recupere dans ma fonction : 1 2 3 dudu
voici votre tableau tab2 recupere dans ma fonction : a b c dudu |
Si vous ne souhaitez pas modifier les tableaux d'origine, à vous de créer vos tableaux dans vos fonctions :
...........
...........
print "voici votre tableau tab1 recupere dans ma fonction : @tab1\n";
print "voici votre tableau tab2 recupere dans ma fonction : @tab2\n";
sub affiche{
#on recupere les références
my ($ref1, $ref2) = @_;
# copie de mes tableaux pour que la modification ne soit appliquee que dans la procedure.
my @tableau1_interne = @{$ref1};
my @tableau2_interne = @{$ref2};
push (@tableau1_interne, "dudu");
push (@tableau2_interne, "dudu");
}
resultat :
voici votre tableau tab1 recupere dans ma fonction : 1 2 3
voici votre tableau tab2 recupere dans ma fonction : a b c |
Voilà!!! Les tableaux @tab1 et @tab2 n'ont pas été modifiés !
|
| auteur : Djibril |
Voici un exemple de tableau à deux dimensions (tableaux de tableaux).
my @tab2tab = ([1,2], ["a","b"],["toto","tete"],["djibril","stoyak","vous"]); |
Chaque case du tableau @tab2tab contient une référence à un tableau anonyme, c'est à dire une référence anonyme.
1ère case du tableau @tab2tab => [1,2]
2ème case du tableau @tab2tab => ["a","b"]
3ème case du tableau @tab2tab => ["toto","tete"]
4ème case du tableau @tab2tab => ["djibril","stoyak","vous"]
Petit rappel : un tableau normal s'écrit avec des parenthèses d'où @tab2tab = (..., ...);
un tableau anonyme avec des crochets : [1,2]
@tab2tab contient 4 références anonymes, ainsi pour récupérer la première référence anonyme :
my $ref1 = $tab2tab[0]; c'est à dire $ref1 = [1,2];
my $ref4 = $tab2tab[3]; c'est à dire $ref4 = ["djibril","stoyak","vous"];
Rappel : la première case d'un tableau a pour indice 0. |
Voici comment afficher la valeur "stoyak", c'est à dire la deuxième case du 4 ème tableau anonyme de tab2tab :
my @tab2tab = ([1,2], ["a","b"],["toto","tete"],["djibril","stoyak","vous"]);
my $ref4 = $tab2tab[3];
1) print ${$ref4}[1]; #=> "stoyak"
2) print $$ref4[1]; #=> "stoyak"
3) print ${$tab2tab[3]}[1];#=> "stoyak"
print $$tab2tab[3][1]; #=> ne fonctionnera pas (explication ci dessous)
4) Cas particulier des tableaux à plusieurs dimensions, on peut écrire simplement ainsi
print $tab2tab[3][1]; #=> "stoyak"
5) print $tab2tab[3]->[1]; #ou print $ref4->[1]; => "stoyak" |
Explication 3) :
Je vous avais expliqué plus haut qu'il était possible d'omettre les accolades et vous avez dû vous demander, pourquoi ${$tab2tab[3]}[1]; est correct et pas $$tab2tab[3][1];?
En fait, pour perl, pour des raisons de priorité entre opérateurs, $tab2tab[3] sera considéré comme une référence,
qui n'existe pas. Vous aurez un message d'erreur à l'exécution du script. Si vous utilisez use strict, vous aurez :
Global symbol "$tab2tab" requires explicit package name at ............. |
Pour Perl, $tab2tab[3] est une référence qui n'existe pas car n'a pas était déclarée. Le fait de mettre des accolades permet
clairement d'indiquer que la référence est $tab2tab[3]. Donc soit vous tapez :
print ${$tab2tab[3]}[1]; #=> "stoyak" |
ou bien
my $ref4 = $tab2tab[3]; #on déclare bien la référence $ref4
print $$ref4[1]; #=> "stoyak" et c'est Ok. |
J'espère avoir été clair!!!
Remarque : En général, Dès qu'on parle de tableaux à deux dimensions ou plus, il faudra manipuler les références anonymes.
my @tab2tab = ([1,2], ["a","b"],["toto","tete"],["djibril","stoyak","vous"]);
print $tab2dimension[3][1];#=> stoyak |
Moyen mnémotechnique pour les tableaux à deux dimensions. @tab2dimension => $tab2dimension[LIGNE][COLONNE] Explication schématique de @tab2dimension
([1,2], ["a","b"],["toto","tete"],["djibril","stoyak","vous"]) correspond à
ligne0 --> 1 2
ligne1 --> a b
ligne2 --> toto tete
ligne3 --> djibril stoyak vous |
Exemple : $tab2dimension[3][1] correspond à la ligne 3 et colonne 1, donc c'est stoyak
première ligne => ligne0 et première colonne => colonne 0 (On est dans les tableaux!!!!!!)
Voilà, vous maîtrisez maintenant les références!!! Je vais vous faire un petit résumé ci dessous avec les piéges à éviter.
|
| auteur : Djibril |
Si vous souhaitez savoir si $ref est une référence à un tableau ou un hash, voici une fonction perl my $ref_tableau = \@tableau;
my $ref_hash = \%hash;
print ref($ref_tableau); => ARRAY
print ref($ref_hash); => HASH |
Erreurs à éviter :
- Ne confondez pas $ref{'toto'} et $ref->{'toto'}.
$ref{'toto'} correspond à la valeur de la toto d'un hash nommé ref
$ref->{'toto'} correspond à la valeur d'une reference nommé ref d'un hash |
Prenez pour habitude de donner des noms simples et clairs à vos variables, et de bien commenter vos scripts!!
- Ne pas confondre un tableau (1,2,3) et une référence anonyme à un tableau anonyme [1,2,3]
- Ne pas confondre un hash ("cle" => "valeur") et une référence anonyme à un hash anonyme {"cle" => "valeur"}
- Attention à
&ma_fonction (@tab1, @tab2);
ou &ma_fonction (%hash1, %hash2);
Cela ne fonctionnera pas ! Passez
plutôt des références en argument :
&ma_fonction (\@tab1, \@tab2);
ou &ma_fonction (\%hash1, \%hash2); |
Si vous souhaitez une documentation plus complète, vous pouvez taper perldoc perlref sous windows ou man perlref sous Unix/Linux.
|
Consultez les autres F.A.Q's  
|