有没有一种标准方法可以选择性地从Perl超类继承方法?
或者:是否有一种标准的方法来创建子类,但使来自超类的某些方法在调用时产生“无法定位对象方法”错误有没有一种标准方法可以选择性地从Perl超类继承方法?,perl,oop,inheritance,Perl,Oop,Inheritance,或者:是否有一种标准的方法来创建子类,但使来自超类的某些方法在调用时产生“无法定位对象方法”错误 例如,如果My::Foo继承自My::Bar,并且My::Bar有一个名为dostuff的方法,调用Foo->new->dostuff将以某种非人工/黑客方式死于“找不到对象方法”错误。如果超类是驼鹿类,则可以使用remove\u方法 package My::Foo; use Moose; extends 'My::Bar'; # some code here my $method_name =
例如,如果
My::Foo
继承自My::Bar
,并且My::Bar
有一个名为dostuff
的方法,调用Foo->new->dostuff
将以某种非人工/黑客方式死于“找不到对象方法”错误。如果超类是驼鹿类,则可以使用remove\u方法
package My::Foo;
use Moose;
extends 'My::Bar';
# some code here
my $method_name = 'method_to_remove';
__PACKAGE__->meta->remove_method($method_name);
1;
这在中有记录,应该可以使用,但我不确定。这完全取决于My::Bar和My::Foo的构造方式。如果它们是您的模块,您可能需要研究它们 也可以从类中导入选择函数,如下所示:
use POSIX qw{setsid};
您可以在子类中创建截获方法调用并终止的伪方法
package My::Foo;
our @ISA = 'My::Bar';
use Carp ();
for my $method qw(dostuff ...) {
no strict 'refs';
*$method = sub {Carp::croak "no method '$method' on '$_[0]'"};
}
您甚至可以编写一个模块来执行此操作:
package No::Method;
use Carp ();
sub import {
my $class = shift;
my $caller = caller;
for my $method (@_) {
no strict 'refs';
*{"$caller\::$method"} = sub {
Carp::croak "no method '$method' on '$_[0]'"
};
}
}
然后使用它:
package My::Foo;
our @ISA = 'My::Bar';
use No::Method qw(dostuff);
你为什么要这么做?听起来像是lilke
My::Bar
并不是作为超类的最佳选择,您应该将其公共功能抽象到一个类中,然后作为新类的父类使用。或者更好的方法是使用角色来组成具有共享行为的类。在我看来,继承被高估了,也被过度使用了。我应该澄清一下:我所说的“人为的”方式是指一个死了的虚拟方法。从符号表中删除方法会自动产生特定错误吗?该方法在符号表中的唯一位置是在父包中,在父包中删除该方法将使父包的对象不再工作。在Perl中确实没有一种好的选择性继承方法。您可以创建一个中间包,只从父类导入一些方法,然后从父类继承(但这也涉及符号表操作)。