可以拦截Perl方法调用吗?

Geo*_*Geo 14 perl

你能拦截Perl中的方法调用,用参数做一些事情,然后执行吗?

bri*_*foy 14

是的,您可以拦截Perl子程序调用.在Mastering Perl中,我有一整章关于那种事情.查看Hook :: LexWrap模块,它可以让您无需完成所有细节即可完成.Perl的方法只是子程序.

您还可以创建子类并覆盖要捕获的方法.这是一种稍微好一点的方法,因为这是面向对象编程希望你做的事情.但是,有时人们编写的代码不允许您正确执行此操作.掌握Perl的内容还有很多.


P S*_*ved 7

简单描述一下,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中有框架可以进行方面化,但我希望这可以证明这种方法.


wes*_*wes 6

这看起来像是穆斯的工作!Moose是Perl的一个对象系统,可以做到这一点,还有更多.该文档会比我能解释做一个更好的工作,但你可能想要的是一个方法修改,具体before.

  • 但这取决于问题是什么,问题的提问者没有说明任何细节.可能有人在评估创建新应用程序时采取的方法,在这种情况下,启用Moose将是一种适当且有益的响应. (3认同)

jso*_*son 5

你可以,并且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)

同样,这是一种替代解决方案,根据原始问题可能更合适.使用符号表时可以获得很多乐趣,但是如果您不需要它可能会过度使用并且可能导致难以维护代码.