OVH Cloud OVH Cloud

Copie de hashs

4 réponses
Avatar
Srand
Bonjour a tous,

J'ai un souci lorsque je fais une copie d'un hash qui contient des
references anonymes. En effet, ces references sont egalement copiees,
ce qui fait que si je modifie sur l'une ou l'autre des variables l'un
des champs reference cela a un impact sur les 2 variables !!!

use XML::Quick;
use Data::Dumper;

$data3={
api=> {
'tag' => {
'_attrs' => { 'foo' => 'bar' },
'_cdata' => 'value'
}
}
};
%data4=%{$data3};
%data5=%{$data3};
$data4{api}->{tag}='coucou';
print Dumper {%data4};
print Dumper {%data5};

Comment faire pour que %data4 et %data3 soient bien 2 copies distinctes
du meme hash sans avoir a le reconstruire ?

Merci d'avance.

4 réponses

Avatar
Paul Gaborit
À (at) 27 Sep 2006 07:01:11 -0700,
"Srand" écrivait (wrote):
J'ai un souci lorsque je fais une copie d'un hash qui contient des
references anonymes. En effet, ces references sont egalement copiees,
ce qui fait que si je modifie sur l'une ou l'autre des variables l'un
des champs reference cela a un impact sur les 2 variables !!!

use Data::Dumper;

$data3={
api=> {
'tag' => {
'_attrs' => { 'foo' => 'bar' },
'_cdata' => 'value'
}
}
};
%data4=%{$data3};
%data5=%{$data3};
$data4{api}->{tag}='coucou';
print Dumper {%data4};
print Dumper {%data5};

Comment faire pour que %data4 et %data3 soient bien 2 copies distinctes
du meme hash sans avoir a le reconstruire ?


Sans le reconstruire ? C'est quasiment impossible. En fait cela
reviendrait à effectuer de la copie retardée. C'est faisable en Perl
mais relativement difficile à implémenter (et on ne passe plus par de
simples références).

Sinon, pour éviter de faire la copie soi-même, on peut passer par
différents mécanismes de clonage de structures. Par exemple, en
utilisant le module Storable :

use Storable qw/dclone/;

# ... votre code ...

my %data4 = %{dclone($data3)};
my %data5 = %{dclone($data3)};

# ... la suite ...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Srand

À (at) 27 Sep 2006 07:01:11 -0700,
"Srand" écrivait (wrote):
J'ai un souci lorsque je fais une copie d'un hash qui contient des
references anonymes. En effet, ces references sont egalement copiees,
ce qui fait que si je modifie sur l'une ou l'autre des variables l'un
des champs reference cela a un impact sur les 2 variables !!!

use Data::Dumper;

$data3={
api=> {
'tag' => {
'_attrs' => { 'foo' => 'bar' },
'_cdata' => 'value'
}
}
};
%data4=%{$data3};
%data5=%{$data3};
$data4{api}->{tag}='coucou';
print Dumper {%data4};
print Dumper {%data5};

Comment faire pour que %data4 et %data3 soient bien 2 copies distinctes
du meme hash sans avoir a le reconstruire ?


Sans le reconstruire ? C'est quasiment impossible. En fait cela
reviendrait à effectuer de la copie retardée. C'est faisable en Perl
mais relativement difficile à implémenter (et on ne passe plus par de
simples références).

Sinon, pour éviter de faire la copie soi-même, on peut passer par
différents mécanismes de clonage de structures. Par exemple, en
utilisant le module Storable :

use Storable qw/dclone/;

# ... votre code ...

my %data4 = %{dclone($data3)};
my %data5 = %{dclone($data3)};

# ... la suite ...



C'est vraiment parfait Paul. Exactement ce que je cherchais. Par
differents mecanismes de clonage tu entends donc qu'il y en a d'autres.
Si cela joue sur les performances je suis preneur.

Merci.


Avatar
Paul Gaborit
À (at) 27 Sep 2006 07:41:57 -0700,
"Srand" écrivait (wrote):
[...] Par differents mecanismes de clonage tu entends donc qu'il y
en a d'autres. Si cela joue sur les performances je suis preneur.


Il y en a d'autres. Par contre, je n'ai jamais comparé leurs
performances respectives.

On peut, par exemple, utiliser Data::Dumper (mais, là, c'est sûr:
c'est moins efficace que Storable).

Il y aussi le module Clone (sur CPAN) qui s'annonce comme plus rapide
que Storable. À voir donc... Si vous faites des tests, donnez-nous les
résultats.

Pour les autres (sans compter le home made), ma mémoire me joue de
tours... ;-)

Par ailleurs, si la performance est vraiment un enjeu et si les
modifications à faire sont peu nombreuses et portent sur des copies de
grosses structures, l'implémentation d'un mécanisme de copie retardée
automagique peut devenir très intéressant.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Srand

À (at) 27 Sep 2006 07:41:57 -0700,
"Srand" écrivait (wrote):
[...] Par differents mecanismes de clonage tu entends donc qu'il y
en a d'autres. Si cela joue sur les performances je suis preneur.


Il y en a d'autres. Par contre, je n'ai jamais comparé leurs
performances respectives.

On peut, par exemple, utiliser Data::Dumper (mais, là, c'est sûr:
c'est moins efficace que Storable).

Il y aussi le module Clone (sur CPAN) qui s'annonce comme plus rapide
que Storable. À voir donc... Si vous faites des tests, donnez-nous les
résultats.

Pour les autres (sans compter le home made), ma mémoire me joue de
tours... ;-)

Par ailleurs, si la performance est vraiment un enjeu et si les
modifications à faire sont peu nombreuses et portent sur des copies de
grosses structures, l'implémentation d'un mécanisme de copie retard ée
automagique peut devenir très intéressant.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>


Merci pour tous ces renseignements precieux.
Je vais voir du cote du module Clone.