1
push (@{$processor{$-[0]}}, $metadata[$_]{"formatters"});
foreach my $key (keys @{$metadata[$_]{"formatters"}}) {
    $metadata[$_]{"formatters"}[$key]{"scope"} = "end";
}
push (@{$processor{$+[0]}}, $metadata[$_]{"formatters"});

我推$metadata[$_]{"formatters"}@{$processor{$-[0]}}。然后我需要改变一些东西并再次推动它,但这些改变也反映在我首先推动的地方。好像我是通过$metadata[$_]{"formatters"}引用而不是按值传递它,但我找不到,如何按值传递它。

4

3 回答 3

4

由于$metadata[$_]{'formatters'}它本身就是一个复杂的数据结构,它本身没有“价值”。不过,您可以推送它的副本。

只做一个浅拷贝(可能不是你想要的,因为新数组仍然会引用所有相同的哈希):

$orig = $metadata[$_]{'formatters'};
$copy = [ @$orig ];

还要复制每个引用的哈希:

$orig = $metadata[$_]{'formatters'};
$copy = [ map +{%$_}, @$orig ];

或者只是复制任意数据结构:

$copy = Storable::dclone($orig);

(CPAN 上有各种克隆模块也可以做到这一点。)

于 2013-02-22T23:18:21.290 回答
1

我很担心你的设计。像这样的结构

$metadata[$_]{formatters}[$key]{scope}

很复杂,而且您似乎有多个非常相似的数据副本。

但是,问题在于它$metadata[$_]{formatters}是对哈希数组的引用。无论您将该引用放在何处,它都会引用相同的数据,因此修改它将反映在对它的任何引用中。

您需要在修改哈希数组之前将其复制到相同的数据结构中,您可以使用此代码执行此操作。我怀疑该数组是一个稀疏数组(即并非所有元素都包含数据)并进行了相应编码。如果我错了,并且每个元素都是哈希引用,那么您可以将其简化为my $copy = [ map { {%$_} } @$formatters ].

my $formatters = $metadata[$_]{formatters};

{
  my $copy = [ map $_ ? {%$_} : undef, @$formatters ];
  push @{$processor{$-[0]}}, $copy;

  for my $key (0 .. $#$copy) {
    $copy->[$key]{scope} = 'end';
  }
}

{
  my $copy = [ map $_ ? {%$_} : undef, @$formatters ];
  push @{$processor{$+[0]}}, $copy;
}
于 2013-02-22T23:40:11.327 回答
-1

这段代码甚至不会编译。您正在调用 @{$metadata[$_]{"formatters"}} 上的键,这不是哈希,而是数组。

这个问题不正确。

这段代码非常复杂且难以理解。我强烈建议在嵌套这样的结构时使用 -> 表示法,以清楚地表明您正在使用对子结构的引用。

要对结构进行深度复制,以免最终获得对子组件的引用,我建议您进行克隆。例如:

use Clone qw(clone);
push (@{$processor{$-[0]}}, clone($metadata[$_]{"formatters"}));

于 2013-02-22T23:29:36.870 回答