加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl,子例程覆盖,调用其父级|参考

发布时间:2020-12-16 06:23:18 所属栏目:大数据 来源:网络整理
导读:我编写了一个将从主脚本加载的Perl模块.该模块使用在主脚本中定义的子程序(我不是维护者). 对于主脚本中的一个子例程,需要扩展,但我不想修补主脚本.相反,我想覆盖我的模块中的函数并保存对原始子例程的引用.如果调用覆盖,我想调用原始子例程,然后进行一些额
我编写了一个将从主脚本加载的Perl模块.该模块使用在主脚本中定义的子程序(我不是维护者).

对于主脚本中的一个子例程,需要扩展,但我不想修补主脚本.相反,我想覆盖我的模块中的函数并保存对原始子例程的引用.如果调用覆盖,我想调用原始子例程,然后进行一些额外的处理(如果需要).

同情模块代码

my $referenceToOriginalSub;

sub inititialize()
{
    $referenceToOriginalSub = &;originalSub;
    undef &originalSub;
    *originalSub = &;overrideSub;
}

sub overrideSub()
{
    #call original within mainscript
    &$referenceToOriginalSub(@_);
    # do some additional processing if required
}

这不起作用,因为它最终会产生无限递归.显然,对originalSub的引用也指向它的替代.

所以,请你指出正确的方向如何避免无限递归?

解决方法

有一个主要的程序

#! /usr/bin/env perl

use strict;
use warnings;

use MyModule;

sub mainsub {
  print "Original mainsubn";
}

mainsub;

并包含MyModule.pm

package MyModule;

use strict;
use warnings;

my $referenceToOriginalSub;

sub overrideSub {
  print "Override: entern";

  $referenceToOriginalSub->(@_);
  # alternative:
  # goto $referenceToOriginalSub;

  print "Override: leaven";
}

INIT {
  no warnings 'redefine';
  $referenceToOriginalSub = &;main::mainsub;
  *main::mainsub = &;overrideSub;
}

1;

INIT块在运行时开始执行程序之前运行.这样做允许使用MyModule来在主程序中定义mainsub之前,并且仍然可以抓住任何子风的句柄.

如果您担心在调用堆栈中屏蔽副作用,则可以使用goto $referenceToOriginalSub,但这只允许执行前模式 – 不执行后执行或执行.

输出:

Override: enter
Original mainsub
Override: leave

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读