我尝试在某些子类中拦截不存在的方法调用。 是的,我知道AUTOLOAD, 但是(对于方法)它首先尝试调用parent ::方法,然后调用UNIVERSAL ::方法然后调用:: AUTOLOAD。 但我首先需要调用(例如):: AUTOLOAD。 因为我想知道子类尝试从父类调用什么方法。
请给我一些建议。
答案 0 :(得分:1)
如果您只想知道正在使用哪些方法,可以使用一些分析模块,如Devel :: NYTProf。
如果您想在程序执行期间对此做出反应,您可以像剖析模块一样直接拦截井上操作码。有关更多详细信息,请参阅perlguts或profiling模块代码。
您可以使用FETCH和EXISTS创建一个'Monitor'类,并将其绑定到符号表哈希,如:tie%Module :: Name ::,Monitor;
但除非我们确切地知道你要做什么以及为什么,否则很难猜出什么是适合你的解决方案。
答案 1 :(得分:1)
请大力考虑Jiri Klouda建议你退后一步,重新考虑你想要完成的事情。你几乎从不想做你想做的事。
但是,如果你确实确定你想要,那么就是如何获得足够纯粹的Perl绳索让自己挂起......
subs pragma将预先列出的子名称列表。正如tchrist所说,你可以预先确定潜艇,但从未真正定义它们。这将短路方法分配到超类并立即调用您的AUTOLOAD。
至于要传递给编译指示的子名称列表,您可以使用Class::Inspector->methods(感谢Nic Gibson's answer教我这个模块。)
根据brian d foy对Nic Gibson的回答的评论,Class :: Inspector将不会处理UNIVERSAL中定义的方法。如果您需要单独执行这些操作,可以从我的Class::LazyObject模块中的“use subs”行获取灵感。
答案 2 :(得分:0)
为什么不在子类包中创建一个AUTOLOAD
子,1)报告丢失的方法然后2)将调用分派给父类。为此,不在子类中定义@ISA
。
类似的东西:
package my_parent;
sub foo { warn "in my_parent::foo" }
package my_subclass;
my $PARENT_CLASS = "my_parent"; # assume only one parent
# Note: no @ISA defined here
sub AUTOLOAD {
warn "non-existent method $AUTOLOAD called\n";
my $self = shift;
(my $method = $AUTOLOAD) =~ s{.*::}{};
my $super = $PARENT_CLASS . '::' . $method;
$self->$super(@_);
}
package main;
my $x = bless {}, 'my_subclass';
$x->foo;
语法:$self->$super(@_)
其中$super
有双冒号,告诉perl在哪个包中开始寻找方法,例如:
$self->my_parent::foo(...)
将在foo
包中开始查找my_parent
方法,而不管哪个类$self
被祝福。