Perl - 子例程“Hash::Merge::merge”的深度递归

2023-11-30

下列的this问题,我在那里使用了答案(也发布在这里),现在我失败了。 我知道失败可能来自于“return bless $self->merge($left, $right), $class_left;”,但我不明白可能是什么问题。

My code:

#!usr/bin/perl
use strict;
use warnings;
use Hash::Merge;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
use Data::Structure::Util qw(unbless);


my $hash1 = bless( {
    'Instance' => {
        'pipe_2' => {
            'LineNumber' => bless( do{\(my $o = '200773952')}, 'Veri::ColLineFile' )
        }
    },
}, 'IB' );

my $hash2 = bless( {
    'Instance' => {
        'pipe_2' => {
            'LineNumber' => bless( do{\(my $o = '200773952')}, 'Veri::ColLineFile' )
        }
    },
}, 'IB' );

my $merger = Hash::Merge->new('LEFT_PRECEDENT');
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);
    print("left = $left, class_left = $class_left right = $right, class_right = $class_right \n");  # I ADDED THIS LINE FOR DEBUGGING
    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);
    }
};
my $hash3 = $merger->merge($hash2, $hash1);

print Dumper($hash3);

Output:

Deep recursion on subroutine "Hash::Merge::merge" at ../rrr line 40.
Deep recursion on anonymous subroutine at ...../freeware/cpan/5.18.4/1/el-7-x86_64/lib/perl5/Hash/Merge.pm line 227.

添加调试行后:

left = SCALAR(0x2db6d70), class_left = SCALAR right = SCALAR(0x2db6d88), class_right = SCALAR
left = SCALAR(0x2db7268), class_left = SCALAR right = SCALAR(0x2db7280), class_right = SCALAR
left = SCALAR(0x2db7760), class_left = SCALAR right = SCALAR(0x2db7778), class_right = SCALAR
left = SCALAR(0x2db9e40), class_left = SCALAR right = SCALAR(0x2db9e58), class_right = SCALAR
left = SCALAR(0x2dba338), class_left = SCALAR right = SCALAR(0x2dba350), class_right = SCALAR
left = SCALAR(0x2dba830), class_left = SCALAR right = SCALAR(0x2dba848), class_right = SCALAR
left = SCALAR(0x2dbad28), class_left = SCALAR right = SCALAR(0x2dbad40), class_right = SCALAR
.... #endless lines

*** 编辑后:***

这个案例(神秘地)确实有效。

my $hash1 = bless( {
    'Instance' => {
        'pipe_2' => {
            'veri_id' => [
                bless( do{\(my $o = '201142064')}, 'Verific::VeriIdDef' )
            ]
        }
    },
}, 'IB' );

my $hash2 = bless( {
    'Instance' => {
        'pipe_2' => {
            'veri_id' => [
                bless( do{\(my $o = '201142064')}, 'Verific::VeriIdDef' )
            ]
        }
    },
}, 'IB' );

问题是unbless递归地祝福其参数内的所有对象。引用其文档:

请注意,该结构会在受祝福的对象内部查找其他要取消祝福的对象。

在您的示例中,您的 2 个对象受到祝福,并且它们每个都包含一个内部受祝福的对象。做完之后unbless $left,两者的祝福都被移除,并且你永远无法恢复内部的。

要解决这个问题,您可以编写自己的实现unbless如下(为简单起见,假设不必处理 typeglob):

sub unbless {
    my $r = eval { ${$_[0]} };
    return \$r unless $@;
    $r = eval { [ @{$_[0]} ] };
    return $r unless $@;
    $r = eval { +{ %{$_[0]} } };
    return $r unless $@;
    die "Unable to unbless.";
}

这个函数的想法是,你可以像解引用一个未祝福的引用一样取消引用一个受祝福的引用,然后你可以获取被取消引用的对象的引用,而这不会受到祝福。除此之外,您需要知道引用的基础类型(标量、arrayref、hashref)。功能unbless上面尝试了所有这些eval,并返回有效的那个。

请注意,它不会修改其参数,而是返回一个不被祝福的等价物。这意味着你需要做$left = unbless $left代替unbless $left。另外,不要忘记删除use Data::Structure::Util.

当前代码存在第二个问题:它不处理标量引用,它将永远循环。您可以通过添加针对该情况的简单检查来解决此问题:

$behavior->{SCALAR}{SCALAR} = sub {
    my $self  = &Hash::Merge::_get_obj;
    my ($left, $right) = @_;
    my ($class_left, $class_right) = (ref $left, ref $right);
    print("left = $left, class_left = $class_left right = $right, class_right = $class_right \n");  # I ADDED THIS LINE FOR DEBUGGING
    if ($class_left && $class_left eq $class_right) {
        if ($class_left eq 'SCALAR') {
            return \($self->merge($$left, $$right));
        } else {
            $left = unbless($left);
            $right = unbless($right);
            return bless $self->merge($left, $right), $class_left;
        }
    } else {
        # Regular scalars, use old behavior
        return $old_behavior_scalar_scalar->($left, $right);
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Perl - 子例程“Hash::Merge::merge”的深度递归 的相关文章

  • Python 递归搜索带有嵌套键的字典

    我最近必须使用嵌套的字典 列表组合来解决实际数据系统中的问题 我为此工作了很长一段时间并提出了解决方案 但我非常不满意 我不得不求助于使用globals 和一个命名的临时全局参数 我不喜欢使用全局变量 这只是要求注入漏洞 我觉得必须有一种更
  • 更新命令行输出

    我的程序 碰巧是用 Perl 编写的 尽管我不认为这个问题是 Perl 特定的 在程序中的某一点输出状态消息 Progress x yy where x and yy是一个数字 例如 Progress 4 38 我想在打印新的状态消息时 覆
  • Perl 脚本(或任何东西)来合计 CSV 列

    我写了 在其他人的很多帮助下 awk command https stackoverflow com questions 4159224 excel and awk disagree about csv totals 4159404 415
  • 如何检测已更改的网页?

    在我的应用程序中 我使用 LWP 定期获取网页 无论如何 是否要检查两次连续提取之间网页是否在某些方面发生了变化 除了明确进行比较之外 是否有在较低协议层生成的任何签名 例如 CRC 可以提取并与旧签名进行比较以查看可能的更改 有两种可能的
  • Perl 删除目录中的所有文件

    我怎样才能删除allPerl 中目录中的文件 不删除目录 我的主机只允许最多 250 000 个 文件 而我的 tmp 文件夹会在所有会话 cookie 运行的情况下快速填充 250 000 个 qouta 在这种情况下我无法删除 tmp
  • 如何在没有循环的情况下初始化哈希中的值?

    我正在尝试找出一种无需经过循环即可初始化哈希的方法 我希望使用切片来实现这一点 但它似乎没有产生预期的结果 考虑以下代码 usr bin perl use Data Dumper my hash hash currency symbol B
  • 如何根据递归关系确定递归树的高度?

    如何确定在处理递归运行时时构建的递归树的高度 它与确定普通树的高度有何不同 替代文本 http homepages ius edu rwisman C455 html notes Chapter4 ch4 9 gif http homepa
  • Perl 中的布尔函数应该返回什么值?

    简短的问题 在 Perl 代码库中一致表示真假的最佳方法是什么 1 0 1 Perl 原生布尔运算符的特殊空字符串 return undef 即空列表 问题背景 我们都知道 Perl 在布尔值方面非常灵活 就像大多数事情一样 例如 Perl
  • 这可以一行完成吗?

    我像这样提取MAC地址 my tmp split domain 123 123 123 123 at 00 11 22 33 44 55 ether on eth0 my vip tmp 3 但不使用临时变量可以完成吗 是的 它可以 my
  • 如何在不进行尾调用优化的情况下用函数式编程替代方案替换 while 循环?

    我正在 JavaScript 中尝试一种更实用的风格 因此 我用诸如map和reduce之类的实用函数替换了for循环 然而 我还没有找到 while 循环的功能替代品 因为尾部调用优化通常不适用于 JavaScript 据我了解 ES6
  • 如何为不同的 Perl 应用程序安装专门的环境?

    就功能而言是否有与 Python 相同或接近的东西虚拟环境 http pypi python org pypi virtualenv what it does 但是对于 Perl 来说呢 我已经用 Python 进行了一些开发 并且将非系统
  • unix df 上的正则表达式帮助

    我需要一些帮助来调整我的代码以查找此 UNIX 中的另一个属性df output Ex Filesystem Size Used Avail Capacity Mounted on dev ad4s1e 61G 46G 9 7G 83 ho
  • 我应该对算法使用递归还是记忆化?

    如果我可以选择使用递归或记忆来解决问题 我应该使用哪一个 换句话说 如果它们都是可行的解决方案 因为它们提供了正确的输出并且可以在我正在使用的代码中合理地表达 那么我什么时候会使用其中一个而不是另一个 它们并不相互排斥 您可以同时使用它们
  • 为什么我只得到第一个捕获组?

    https stackoverflow com a 2304626 6607497 https stackoverflow com a 2304626 6607497 and https stackoverflow com a 370042
  • 根据插入顺序迭代哈希?

    不想对条目进行排序 使用它也不会保留顺序 foreach my val keys hash 默认情况下 Perl 5 中的哈希值是无序的 您可以使用tie http perldoc perl org functions tie html a
  • 将嵌套数组中的“点符号”键扩展到子数组

    我从某个任意深度的嵌套数组开始 在该数组中 一些键是一系列由点分隔的标记 例如 billingAddress street 或 foo bar baz 我想将这些键控元素扩展到数组 因此结果是一个嵌套数组 其中所有这些键都已扩展 例如 bi
  • 当满足动态条件时退出递归函数

    使用来自的函数生成汉明距离 t 内的所有比特序列 https stackoverflow com questions 40813022 generate all sequences of bits within hamming distan
  • 是否有理由在 Perl 中使用 open(...) 的双参数形式?

    是否有任何理由使用双参数形式open 在 Perl 中而不是三个或更多参数的版本 我能想到的唯一原因是明显的观察结果 即两个参数的形式更短 但是假设冗长不是问题 是否有任何其他原因会让您选择双参数形式open 一参数和二参数 open 应用
  • 在 Ada 中使用递归绘制保龄球瓶(金字塔)

    我知道这是通过展示我最不复杂的作品来推动社区的善意 期待有人来拯救我 但我别无选择 没有什么可失去的 过去几周我已经浏览了数据包 文件 类型 标志和框 但没有涉及太多递归 特别是不要用递归来绘图 我的考试大约还有一周时间 我希望有足够的时间
  • 在perl中更改多维哈希的第一个键

    我在 perl 中有一个多维哈希 我想更改所选值的第一个键 例如 我有哈希 my Hash1 Hash1 1 12 1 Hash1 1 10 1 Hash1 2 31 1 Hash1 3 52 1 Hash1 3 58 1 Hash1 4

随机推荐

  • Py_Initialize 和 Py_finalize 以及 MatPlotlib

    这是一个已知问题 但我想请专家为我解决这个问题的最佳方法 我有一个项目 Euler Math Toolbox 它运行 Python 作为脚本语言 为此 在运行时加载库模块 python dll 该模块链接到 python27 lib 然后调
  • 如何在 python http.server 上使用 ES6 模块?

    我正在实例化一个模块 如下所示index html index js是空的 当我通过以下方式提供此服务时py 3 m http server Python 3 8 5 我收到 Chrome 错误 Failed to load module
  • Angular 2“组件”不是已知元素

    我正在尝试在其他模块中使用我在 AppModule 内创建的组件 但我收到以下错误 未捕获 承诺 错误 模板解析错误 contacts box 不是已知元素 如果 contacts box 是 Angular 组件 则验证它是否是该模块的一
  • 纯 CSS 卡片的重叠效果

    我正在制作与此示例类似的卡片列表 https codepen io pkunzel pen xxgjrVg window addEventListener load function let cards document querySele
  • 膨胀类 android.support.v7.app.AlertController.RecycleListView 时出错

    我的应用程序无法启动 安装后立即崩溃 我无法理解该错误 我为附加在主活动 xml 文件中的两个片段创建了两个 recyclerView Error E AndroidRuntime FATAL EXCEPTION main Process
  • 在循环内将引号粘贴到字符串中

    使用 R 我想生成多个字符串 例如 modelCheck var1 d bug modelCheck var2 d bug modelCheck var10 d bug 我通常会使用 for 循环并粘贴 如果我不必担心双引号 如下所示 fo
  • 为什么 Collections.Counter 没有对称差异?

    因此 对于集合 您可以执行对称差 这相当于并减交集 为什么 是 Counter 对象不受支持的操作数 而并集和交集仍然有效 扩展我的评论 结果发现它当时被讨论过 但被拒绝了 单击完整消息 及其主题 的链接 我将引用 Raymond Hett
  • 如何移动正交图中的点?

    我正在尝试在迈克 博斯托克创建的以下地图上的某些地理位置添加红点 https bl ocks org mbostock 3795040 我的点会显示 但不会随地图移动 如何编辑代码以使点随地图移动 谢谢 add circles to svg
  • 如何使用javascript从mysql数据库获取数据?

    如果可能的话 如何使用 javascript 从 mysql 数据库获取 并发布 数据 我知道我可以使用 php 和其他语言 但我只需要知道这是否可以用 javascript 实现 提前致谢 这对于 Javascript 来说是不可能的 我
  • 如何响应 UNUserNotification 上的点击?

    我正在使用新的UNUserNotificationiOS 10 中的框架 我可以看到如何添加操作按钮 但是当用户点击通知本身时我如何响应 就我而言 它将是带有一些文本的图像 默认行为是应用程序打开 我可以使用自定义代码来检测我的应用程序是否
  • 如何在pyodbc中使用executemany运行多个SELECT查询

    我使用 PYODBC 根据 pandas 数据帧列的值多次查询 SQL DB 如下所示为值列表 因为我使用 ToList 函数将该列转换为列表 the connection string cnxn pyodbc connect driver
  • 扫描随机数量的浮点数,直到 C 中出现新行

    我正在尝试从包含以下文本的文件中读取 502 601 596 465 464597 599 600 598602 591 596 601588 565 548 260 62 61 595583 595 61 558 561237 241 4
  • 分析 C# 中的方法以了解其运行时间

    我需要获取计时报告以了解在类中运行 C 方法需要多长时间 我考虑使用profiler要做到这一点 输入是类中方法的名称 输出是 什么方法 类调用这个方法 运行该方法的时间量 有哪些工具 商业产品可用于 Visual Studio 2010
  • 在 TypoScript 中获取 FlexForm 配置

    我需要从 pi flexform 获取 typescript 中的 page headerData 如何实现我的要求 page PAGE page headerData 10 TEXT 10 value 我不太确定你真正需要什么 我是gue
  • SlidingDrawer 动画速度

    我是 Android 编程和堆栈溢出的新手 我需要减慢应用程序中 SlidingDrawer 的动画速度 我已经像这样子类化了 SlidingDrawer import android content Context import andr
  • 最大化两个数组元素的乘积之和的算法

    竞赛中有一个问题需要计算仅包含数学和生物科目的班级的表现 所以 没有 数学学生 n 没有 的生物学生 每个学生都有一个单独的分数 数学学生和生物学生的分数分别存储在数组 mathScore 和 bioScore 中 全班成绩计算如下 mat
  • 从存储过程填充 DataGridView

    我使用 SQL Server 2008 创建了一个名为 MyStoreProc 的存储过程 它在管理工具中运行良好 在 VB Net 2008 中 我创建了一个新的数据集和一个新的 TableAdaptor 在此表适配器中 我创建了一个名为
  • 如何从树状数组创建 ul - li 菜单?

    我有一个数组title and children index title始终不为空 children是一个数组 空或非空 Any children have title and children等等 myArray 0 gt title g
  • JTable右键复制/粘贴菜单一键复制单元格数据

    我创建了我的JPopupMenu 它出现在我的JTable当我右键单击一个单元格时 但是 我无法复制单元格中的数据 除非我首先双击然后突出显示数据 然后右键单击当前单元格以外的任何位置以显示弹出菜单和复制选项 我想复制单元格中的数据 而不必
  • Perl - 子例程“Hash::Merge::merge”的深度递归

    下列的this问题 我在那里使用了答案 也发布在这里 现在我失败了 我知道失败可能来自于 return bless self gt merge left right class left 但我不明白可能是什么问题 My code usr b