Ответ 1
use Storable qw(dclone);
$group2 = dclone(\%group);
Возможный дубликат:
Каков наилучший способ сделать глубокую копию структуры данных в Perl?
Прежде чем я начну кодировать это сам и заново изобретать колесо, как вы копируете хэш хэшей, не дублируя hashrefs?
Я читаю хэш хэш хэшей через Config::General. то есть структура данных:
my %config = ( group => { item1 => { foo => 'value',
bar => 'value',
},
item2 => { foo => 'value',
bar => 'value',
},
item3 => { foo => 'value',
bar => 'value',
},
},
);
Затем я вывожу свою группу из конфигурации, разыменовывая ее и изменяя содержимое во время выполнения до перезаписи файла конфигурации:
my %group = %{$config{'group'}};
Проблема в том, что мне нужно проверить, были ли внесены изменения и внесение связанных изменений в структуру файловой системы. Я не могу этого сделать, проверив:
if ($group{'item1'}{'foo'} ne $config{'group'}{'item1'}{'foo'}) {
### Stuff!
}
как $group{'item1'}
и $config{'group'}{'item1'}
являются одинаковыми хэш файлами.
Теперь, когда нужно просто повторно проанализировать файл конфигурации и сравнить проанализированную копию с диском с отредактированной версией непосредственно перед сохранением на диск, я уверен, что есть способ вставить разыменованную сложная структура данных, копирование содержимого хэш-ссылок, а не просто копирование самих ссылок. Беглый экзамен по CPAN ничего не меняет. Что мне не хватает?
Benchmark
Получил свой ответ:
#!/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 }},
});
приводит к:
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)
use Storable qw(dclone);
$group2 = dclone(\%group);
В документации Storable:: dclone я нашел Clone:
my $copy = clone (\@array);
# or
my %copy = %{ clone (\%hash) };
Не требуется гибкость и утверждает, что он быстрее, чем Storable:: dclone.
Глубокая структура данных 101:
dclone
, чтобы сделать глубокую копию структуры и freeze
и thaw
для сериализации/десериализации их для хранения (скажем, в базе данных или в http файле cookie (но вы должны шифровать все, что вы отправляете пользователю, чтобы затруднить вмешательство).Может всегда хранить хэш через Storable или Data:: Dumper и переназначать сохраненное значение в новый хеш. Это должно получить полную копию, не поддерживая ссылки, ссылки.
use Storable;
my $serialized = freeze \%config;
my %newconfig = %{ thaw($serialized) };