Hash::Merge
认为任何事物ref
isn't HASH
or ARRAY
是标量,并对这些项目应用标量合并规则(请参阅那些行的实施情况Hash::Merge
)。合并 2 个标量时,Hash::Merge
要么丢弃其中之一,要么创建一个数组来存储它们。这些选项都不会合并祝福的哈希值。
要解决这个问题,您可以先取消哈希值的加密(使用Data::Structure::Util::unbless例如),然后合并它们,然后重新祝福它们:
use Data::Structure::Util qw(unbless);
my $class = ref $hash1;
unbless $hash1;
unbless $hash2;
my $hash3 = bless $merger->merge($hash2, $hash1), $class;
如果您的主哈希中有受祝福的哈希,那么您可以定义自己的哈希Hash::Merge
行为与add_behavior_spec方法:对于SCALAR
-SCALAR
在这种情况下,检查两个标量是否都是被祝福的引用,如果是,则取消祝福、合并和重新祝福:
$merger->add_behavior_spec(
{ 'SCALAR' => {
'SCALAR' => sub {
my $self = &Hash::Merge::_get_obj;
my ($left, $right) = @_;
my ($class_left, $class_right) = (ref $left, ref $right);
if ($class_left && $class_left eq $class_right) {
unbless $left;
unbless $right;
return bless $self->merge($left, $right), $class_left;
} else {
return $_[1]; # Or something else
}
},
'ARRAY' => ...,
'HASH' => ...,
},
ARRAY => { ... },
HASH => { ... }
为了简洁起见,我离开了...
对于不相关的情况。您可以从以下位置复制粘贴这些内容的来源Hash::Merger(选择您想要的行为)。或者,也许更简单,您可以使用get_behavior_spec and get_behavior方法来改变SCALAR
-SCALAR
当前行为的情况:
my $behavior = $merger->get_behavior_spec($merger->get_behavior);
my $old_behavior_scalar_scalar = $behavior->{SCALAR}{SCALAR};
$behavior->{SCALAR}{SCALAR} = sub {
my $self = &Hash::Merge::_get_obj;
my ($left, $right) = @_;
my ($class_left, $class_right) = (ref $left, ref $right);
if ($class_left && $class_left eq $class_right) {
unbless $left;
unbless $right;
return bless $self->merge($left, $right), $class_left;
} else {
# Regular scalars, use old behavior
return $old_behavior_scalar_scalar->($left, $right);
}
};
请注意,这不能很好地处理您想要合并 2 个受祝福的 2 个不同包的哈希值的情况。您必须为这些实施特殊情况。 (尚不清楚合并此类哈希的一般规则是什么)