Quelle est la meilleure façon de copier un hachage de hash en Perl? [dupliquer]
possibilité de duplication:
Quelle est la meilleure façon de faire une copie profonde d'une structure de données en Perl?
avant que je commence à coder moi-même et à réinventer la roue, comment copier un hachage de hachages sans dupliquer les hachoirs?
je lis un hash de hash de hash via Config::General . c'est à dire, la structure des données est la suivante:
my %config = ( group => { item1 => { foo => 'value',
bar => 'value',
},
item2 => { foo => 'value',
bar => 'value',
},
item3 => { foo => 'value',
bar => 'value',
},
},
);
je retire alors mon groupe de la config en le déréférencant et en changeant le contenu à l'exécution avant de réécrire le fichier de configuration:
my %group = %{$config{'group'}};
le problème est que je dois vérifier pour voir si des changements ont été faits et d'apporter des changements associés à la structure du système de fichiers. Je ne peux pas le faire en cochant:
if ($group{'item1'}{'foo'} ne $config{'group'}{'item1'}{'foo'}) {
### Stuff!
}
comme $group{'item1'}
et $config{'group'}{'item1'}
sont tous les deux les mêmes hashref.
maintenant alors qu'il devrait être trivial de simplement re-analyser le fichier de configuration, et comparer la copie parsée à partir du disque par rapport à la version éditée juste avant de sauvegarder sur le disque, je suis sûr qu'il y a un moyen d'obtenir une déréférence imbriquée d'une structure de données complexe, en copiant le contenu des références hachées et pas simplement en copiant les références elles-mêmes. Un examen superficiel de la CPAN ne révèle rien. Ce qui me manque?
de Référence
Eu ma réponse:
#!/usr/bin/perl
use Benchmark qw(:all) ;
use Storable qw(dclone);
use Clone qw(clone);
my %config = ( group => { item1 => { foo => 'value',
bar => 'value',
},
item2 => { foo => 'value',
bar => 'value',
},
item3 => { foo => 'value',
bar => 'value',
},
},
);
my $ref = $config{'group'};
timethese(100000, {
'Clone' => sub { my %group = %{ clone $ref }},
'Storable' => sub { my %group = %{ dclone $ref }},
});
résultats dans:
Benchmark: timing 100000 iterations of Clone, Storable... Clone: 2 wallclock secs ( 2.26 usr + 0.01 sys = 2.27 CPU) @ 44052.86/s (n=100000) Storable: 5 wallclock secs ( 4.71 usr + 0.02 sys = 4.73 CPU) @ 21141.65/s (n=100000)
4 réponses
De la Stockables::dclone de la documentation, j'ai trouvé Clone :
my $copy = clone (\@array);
# or
my %copy = %{ clone (\%hash) };
N'ont pas besoin de flexibilité, et prétend être plus rapide que stockable::dclone .
Profondeur structure de données 101:
- Utiliser Stockables 's
dclone
de faire une copie d'une structure, etfreeze
etthaw
pour sérialiser/désérialiser pour le stockage (disons dans une base de données, ou un cookie http (mais vous devez chiffrer tout ce que vous envoyez à l'utilisateur afin de le rendre plus difficile à falsifier). - utiliser données::comparer (ou Test:: Deep ou Test:: Differences à l'intérieur d'un test unitaire) pour comparer deux structures de données profondes.
- Utiliser Data::Dumper ou Données::Dump débogage pour voir ce que vos objets. Mais ne l'utilisez pas comme une licence pour altérer les internes d'un autre objet; utilisez L'API. :)
peut toujours stocker le hash via stockable ou Data::Dumper, et réattribuer la valeur stockée dans un nouveau hash. Ceci devrait obtenir une copie complète sans maintenir les liens référencés.
use Storable;
my $serialized = freeze \%config;
my %newconfig = %{ thaw($serialized) };