{%{$self->param}}
它确实散列扩展,然后创建另一个散列引用.
但是不{%{$self->param}}一样$self->param吗?为什么代码打扰这个伎俩呢?
mus*_*iKk 15
它复制哈希.请考虑以下代码段:
use Data::Dumper;
my $foo = { a => 1, ar => [1] };
my $bar = {%$foo};
$bar->{b} = 2;
push @{$bar->{ar}}, 4;
print Dumper $foo;
print Dumper $bar;
它打印
$VAR1 = {
          'a' => 1,
          'ar' => [
                    1,
                    4
                  ]
        };
$VAR1 = {
          'a' => 1,
          'b' => 2,
          'ar' => [
                    1,
                    4
                  ]
        };
因此,您可以看到副本很浅:即使它们是引用,也会复制标量.引用的对象是相同的(在此示例中引用的数组ar).
虽然这两个{%{$self->param}}和$self->param是一个哈希的引用,他们并不指存储在同一个位置的哈希值.
第一个表达式取消引用$self->param哈希,并返回对匿名哈希的引用.在外括号内,%{$self->param}实际上是临时展开和复制,然后返回对此临时副本的引用,而不是旧哈希.
此代码实际上创建了一个副本哈希(键和值的浅表副本,但不是深层副本),返回引用并返回对它的引用.
如果某个子返回引用哈希并且您更改了某些内容,则实际上您正在更改原始哈希中的值.为避免这种情况,我们有时需要在进行任何更改之前复制整个哈希(或数组).
这是一个例子:
sub get_hashref {
    my $hashref = shift;
    return $hashref;
}
my %hash = (foo => 'bar');
my $ref = get_hashref(\%hash);
$ref->{foo} = 'baz'; # Changes 'foo' value in %hash
print "Original 'foo' now is: $hash{foo}\n"; # 'baz'
print "Ref's 'foo' now is: $ref->{foo}\n";   # 'baz'
# But!
$ref = {%{ get_hashref(\%hash) }};
$ref->{foo} = 42; # No changes in %hash
print "Original 'foo' now is: $hash{foo}\n"; # 'baz'
print "Ref's 'foo' now is: $ref->{foo}\n";   # '42'
为了更好地理解,{%{ $self->param }}可以扩展到:
my $ref = $self->param; # Ref to original hash
my %copy = %{$ref}; # Copies keys and values to new hash
my $ref_to_copy = {%copy}; # get ref to it
如果您需要哈希但不参考它,您也可以省略最后一步.