我编写了一个将从主脚本加载的 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/