什么是深拷贝的最佳方式在Perl哈希散列? [重复](What's the best w

2019-07-21 19:34发布

可能重复:
什么是做一个数据结构的深层副本在Perl中的最佳方式?

在我开始这个编码自己,重新发明轮子,你怎么复制哈希散列而非复制hashrefs?

我读通过哈希散列的散列配置::一般 。 即,数据结构是:

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'}都是完全相同的hashref。

现在,虽然它应该是微不足道简单地重新解析配置文件,并只保存到磁盘之前比较来自对编辑的版本盘面解析副本,我敢肯定有办法一个复杂的数据结构嵌套间接引用,复制散列裁判的内容,而不是简单地复制引用自己。 在CPAN粗略检查不把任何东西。 我在想什么?

基准

得到我的回答:

#!/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)

Answer 1:

use Storable qw(dclone);
$group2 = dclone(\%group);


Answer 2:

从可存储:: dclone文档,我发现克隆 :

my $copy = clone (\@array);

# or

my %copy = %{ clone (\%hash) };

不需要灵活性,并声称要快于可保存:: dclone 。



Answer 3:

深层数据结构101:

  • 使用可存储的dclone做出结构的深层副本,并freezethaw序列化/反序列化他们的存储(比如在数据库中,或者一个HTTP cookie(但你应该加密,任何你发送给用户,使之更难篡改)。
  • 使用数据::比较 (或测试::深或测试::差异单元测试中)来比较两个深深的数据结构。
  • 使用数据::自卸车或数据::转储调试,看看你的对象是什么样子。 但不要把它作为一个许可证与另一个对象的内部篡改; 使用API​​。 :)


Answer 4:

总是可以通过存储可保存或数据::自卸车的哈希,并重新分配存储的值到一个新的哈希值。 这应该得到一个完整的副本,不保持引用链接。

use Storable;
my $serialized = freeze \%config;
my %newconfig = %{ thaw($serialized) };


文章来源: What's the best way to deep copy a hash of hashes in Perl? [duplicate]