Perl,通过调用其父程序覆盖子程序 |引用

标签 perl overriding

我编写了一个将从主脚本加载的 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 mainsub\n";
}

mainsub;

MyModule.pm包含
package MyModule;

use strict;
use warnings;

my $referenceToOriginalSub;

sub overrideSub {
  print "Override: enter\n";

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

  print "Override: leave\n";
}

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

1;
INIT block 在运行时开始执行程序之前运行。这样做允许 use MyModule出现在 mainsub 的定义之前在主程序中,仍然能够掌握子程序的任何内容。

您将使用 goto $referenceToOriginalSub 如果您担心屏蔽调用堆栈中的副作用,但这仅允许执行前模式 - 不允许执行后或执行周围。

输出:

覆盖:输入
原始主子
覆盖:离开

关于Perl,通过调用其父程序覆盖子程序 |引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18551133/

相关文章:

perl - 为什么这个 map block 包含一个明显没用的+?

Python:子类之间的引用

java - @Override on 子类 "appears"中的方法在运行时被忽略

java - 为什么要重写接口(interface)方法?

scala - 澄清为什么我不能通过它的子类型覆盖使用泛型类参数的方法

perl - Moose 类的依赖注入(inject)

Perl:如何在不存储到数组的情况下拆分字符串并继续拆分?

multithreading - 在线程之间转发/传递文件描述符

string - Perl 字符串怪异 : equal strings being not equal?

javascript - extjs 4.1.3 Ext.override 列未执行