IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Perl avancé > Les réferences
        Qu'est ce qu'une référence, à quoi ça sert?
        Comment créer une référence?
        Qu'est ce qu'une référence anonyme?
        Comment utiliser les références, le déférencement!
        Cas particulier (tableau à 2 dimensions)!
        Astuces sur les références et erreurs à éviter!

rechercher
precedent    sommaire    suivant    telecharger


Qu'est ce qu'une référence, à quoi ça sert?
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. !


Comment créer une référence?
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
$ref_tab = \@tab ;
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.


Qu'est ce qu'une référence anonyme?
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).


Comment utiliser les références, le 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 !


Cas particulier (tableau à 2 dimensions)!
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.


Astuces sur les références et erreurs à é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.


rechercher
precedent    sommaire    suivant    telecharger

Consultez les autres F.A.Q's

Valid XHTML 1.1!Valid CSS!


Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2005 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.