2011-08-06 3 views
0

Jetez un oeil à ce morceau de code:comportement étrange des références Perl

my @arr = (1, 2); 
my $ref = \@arr; 
my @s = @$ref; 
push @s, 4; 
print join(", ", @arr) . "\n"; 

Contre toute attente, la sortie est "1, 2". Qu'est-il arrivé? Comment se fait-il que j'ai deux tableaux différents (@s is (1,2,4))?

Bien sûr je reçois "1, 2, 4" si j'écris, avant la sortie, quelque chose comme ceci:

$ref = \@s; 
@arr = @$ref; 

Mais cela semble plutôt maladroite.

Je suis habitué à d'autres langages OOP, dans lesquels une telle chose ne se produirait pas - un objet peut être modifié, quelles que soient ses références.

Donc, quelqu'un peut-il m'aider s'il vous plaît avec ça?

Répondre

2
my @s = @$ref; 

fait une copie du tableau référencé. Après cela, @s et @arr sont des tableaux sans rapport qui ont juste le même contenu (pendant un certain temps).

Si vous souhaitez modifier le tableau référencé, vous devez l'utiliser directement, par exemple .:

push @$ref, 4; 

Il y a aussi le module Data::Alias, qui (je pense) vous permet de faire ce que vous demandez. Mais il y a de la magie profonde impliquée là-bas, et je ne l'ai jamais utilisée moi-même.

+0

Nous vous remercions de votre réponse. C'est assez bizarre, non? Est-il possible de "réparer"? Mon intention est la suivante: j'ai une classe, dont un de ses champs est une référence à un tableau. Je souhaite changer ce tableau dans une classe différente, donc j'ai fait @array = @ {$ object -> {array}}; et cela n'a pas fonctionné. Donc, vous dites que la meilleure façon de le faire est d'écrire mon $ ref = $ object -> {array} et d'appuyer sur @ $ ref à chaque fois? – Rob

+0

@Rob, c'est une façon de le faire. En Perl 5.14, vous pouvez écrire 'push $ ref, 4' à la place (déréférencement implicite). Vous pouvez également écrire une méthode 'push_array', puis faire' $ object-> push_array (4) '. [Moose :: Meta :: Attribute :: Native] (http://search.cpan.org/perldoc?Moose::Meta::Attribute::Native) peut aider à simplifier cela. – cjm

+0

D'accord, merci! – Rob