如何覆盖对模块函数的调用,然后在覆盖中引用该原始函数?
How to override calls to a module function and then reference that original function in override?
我有一个巨大的 perl 脚本,它对一个模块中的几个函数进行了数百次调用,我需要跟踪这些函数执行过程中经过了多少时间。
问题:我无法安装 Devel::NYTProf
(无法在我的机器上编译 perl 5.8.8),并且在这两个函数的每个实例周围添加 Devel::Timer
调用会非常困难耗时。
我考虑过重写对这两个函数的调用,在我的重写中执行这两个函数,只用几个 Devel::Timer
调用围绕它。我最初的尝试以递归循环结束。
例如:
use strict;
Use SomePackage::SomeModule;
Use Devel::Timer;
my $t = Devel::Timer->new();
$someThing = new SomePackage::SomeModule();
$someThing->someFunction('test1','test2');
$t->mark('END');
$t->report();
sub SomePackage::SomeModule::someFunction {
$t->mark('start someFunction');
$someThing->someFunction(@_)
$t->mark('end someFunction');
}
这显然行不通,但我没有明确的解决方案。
有什么想法或提示可以帮助我找到正确的方法吗?
my $old_f = \&f;
my $new_f = sub { ... $old_f->(...) ... };
no warnings qw( redefine );
*f = $new_f;
感谢 ikegami 的基础知识,我能够使以下代码正常工作:
use strict;
use SomePackage::SomeModule;
use Devel::Timer;
my $t = Devel::Timer->new();
$someThing = new SomePackage::SomeModule();
my $someFunctionRef = \&SomePackage::SomeModule::someFunction;
my $someFunctionTrack = sub {
$t->mark('start someFunction');
$someFunctionRef->(@_);
$t->mark('end someFunction');
};
no warnings qw( redefine );
*SomePackage::SomeModule::someFunction = $someFunctionTrack;
$someThing->someFunction('test1','test2');
$t->mark('END');
$t->report();
我有一个巨大的 perl 脚本,它对一个模块中的几个函数进行了数百次调用,我需要跟踪这些函数执行过程中经过了多少时间。
问题:我无法安装 Devel::NYTProf
(无法在我的机器上编译 perl 5.8.8),并且在这两个函数的每个实例周围添加 Devel::Timer
调用会非常困难耗时。
我考虑过重写对这两个函数的调用,在我的重写中执行这两个函数,只用几个 Devel::Timer
调用围绕它。我最初的尝试以递归循环结束。
例如:
use strict;
Use SomePackage::SomeModule;
Use Devel::Timer;
my $t = Devel::Timer->new();
$someThing = new SomePackage::SomeModule();
$someThing->someFunction('test1','test2');
$t->mark('END');
$t->report();
sub SomePackage::SomeModule::someFunction {
$t->mark('start someFunction');
$someThing->someFunction(@_)
$t->mark('end someFunction');
}
这显然行不通,但我没有明确的解决方案。
有什么想法或提示可以帮助我找到正确的方法吗?
my $old_f = \&f;
my $new_f = sub { ... $old_f->(...) ... };
no warnings qw( redefine );
*f = $new_f;
感谢 ikegami 的基础知识,我能够使以下代码正常工作:
use strict;
use SomePackage::SomeModule;
use Devel::Timer;
my $t = Devel::Timer->new();
$someThing = new SomePackage::SomeModule();
my $someFunctionRef = \&SomePackage::SomeModule::someFunction;
my $someFunctionTrack = sub {
$t->mark('start someFunction');
$someFunctionRef->(@_);
$t->mark('end someFunction');
};
no warnings qw( redefine );
*SomePackage::SomeModule::someFunction = $someFunctionTrack;
$someThing->someFunction('test1','test2');
$t->mark('END');
$t->report();