Perl - Hash::Merge 丢失 key

标签 perl hashmap

我正在尝试在 Perl 中合并两个受祝福的哈希值。

我正在运行以下代码:

#!usr/bin/perl
use strict;
use warnings;
use Hash::Merge;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;

my $hash1 = bless( {
                 'CalcPorts' => {
                                  'helper_1' => {
                                                  'Scope' => [
                                                               ''
                                                             ],
  
                                                },
                                  'helper_2' => {
                                                  'Scope' => [
                                                               ''
                                                             ],
 
                                                },
                                },
 
               }, 'IB' );
my $hash2 = bless( {
                 'CalcPorts' => {
                                  'helper_2' => {
                                                  'Scope' => [
                                                               'd'
                                                             ],
 
                                                },
                                },
 
               }, 'IB' );

my $merger = Hash::Merge->new('LEFT_PRECEDENT');    
my $hash3 = $merger->merge($hash2, $hash1);

print Dumper($hash3);

输出是这样的:

$VAR1 = bless( {
                 'CalcPorts' => {
                                  'helper_2' => {
                                                  'Scope' => [
                                                               'd'
                                                             ]
                                                }
                                }
               }, 'IB' );

尽管我预计“helper_1”会在那里...... 有什么想法我做错了什么吗? 感谢您的帮助:)

最佳答案

Hash::Merge 认为 ref 不是 HASHARRAY 的任何内容都是标量,并对这些项应用标量合并规则(请参阅 Hash::Merge 实现的 those lines)。合并 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;

如果您的主哈希中有受祝福的哈希,那么您可以使用 add_behavior_spec 定义您自己的 Hash::Merge 行为。方法:对于 SCALAR-SCALAR 情况,检查两个标量是否都是被祝福的引用,如果是,则 unbless、merge 和 rebless:

$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  => { ... }

为了简洁起见,我为不相关的情况留下了...。您可以复制粘贴 the source of Hash::Merger 中的内容(选择您想要的行为)。或者,也许更简单,您可以使用 get_behavior_specget_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 个不同包的哈希值的情况。您必须为这些实现特殊情况。 (尚不清楚合并此类哈希的一般规则是什么)

关于Perl - Hash::Merge 丢失 key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69071202/

相关文章:

Perl 命令行 - 如果找到字符串替换下一行

linux - 我怎么知道我在 perl 脚本中运行的是 64 位还是 32 位 linux?

perl - 为什么 Perlbrew 在 Mac OS X Lion 上启动 bash?

regex - Perl:如何在对变量进行分组后插入数字?

regex - 如何从 Perl 字符串中删除特定字符?

java - hashMap.get ("The String key") 的速度会受到 hashMap 大小的影响吗?

java - 尝试解析嵌套的 json 并将其存储在嵌套的 Map 中。阅读时,它会在 map 中提供额外的值。代码、输出和 json 下面

java - 不使用 null 将空白标记到数组中

java - HashMap/ArrayList 不会为每个键取多个值

java - 在 ConcurrentSkipListMap Java 中插入空值