bri*_*foy 14
是的,您可以拦截Perl子程序调用.在Mastering Perl中,我有一整章关于那种事情.查看Hook :: LexWrap模块,它可以让您无需完成所有细节即可完成.Perl的方法只是子程序.
您还可以创建子类并覆盖要捕获的方法.这是一种稍微好一点的方法,因为这是面向对象编程希望你做的事情.但是,有时人们编写的代码不允许您正确执行此操作.掌握Perl的内容还有很多.
简单描述一下,Perl具有修改符号表的能力.您可以通过该方法所属的包的符号表调用子例程(方法).如果修改符号表(并且这不被认为非常脏),则可以使用调用指定的其他方法替换大多数方法调用.这证明了这种方法:
# The subroutine we'll interrupt calls to
sub call_me
{
print shift,"\n";
}
# Intercepting factory
sub aspectate
{
my $callee = shift;
my $value = shift;
return sub { $callee->($value + shift); };
}
my $aspectated_call_me = aspectate \&call_me, 100;
# Rewrite symbol table of main package (lasts to the end of the block).
# Replace "main" with the name of the package (class) you're intercepting
local *main::call_me = $aspectated_call_me;
# Voila! Prints 105!
call_me(5);
Run Code Online (Sandbox Code Playgroud)
这也表明,一旦有人参考了子程序并通过引用调用它,你就不能再影响这样的调用了.
我很确定在perl中有框架可以进行方面化,但我希望这可以证明这种方法.
你可以,并且Pavel描述了一种很好的方法,但你应该详细说明为什么你想要这样做.
如果您正在寻找拦截对任意子例程的调用的高级方法,那么摆弄符号表将对您有用,但如果您想为可能导出到您当前工作的命名空间的函数添加功能,那么您可能需要了解调用其他命名空间中存在的函数的方法.
例如,Data :: Dumper通常将函数'Dumper'导出到调用命名空间,但您可以覆盖或禁用它并提供您自己的Dumper函数,然后通过完全限定名称调用原始函数.
例如
use Data::Dumper;
sub Dumper {
warn 'Dumping variables';
print Data::Dumper::Dumper(@_);
}
my $foo = {
bar => 'barval',
};
Dumper($foo);
Run Code Online (Sandbox Code Playgroud)
同样,这是一种替代解决方案,根据原始问题可能更合适.使用符号表时可以获得很多乐趣,但是如果您不需要它可能会过度使用并且可能导致难以维护代码.