A.pm:
package A; use Carp qw (croak); use strict; use warnings; sub new { my $class = shift; print "This is A new\n"; my $self->{DEV_TYPE} = shift || "A"; bless($self,$class); return $self; } sub a_func{ print "This is A func\n"; } 1;
B.pm:
package B; use Carp qw (croak); use strict; use warnings; sub new { my $class = shift; print "This is B new\n"; my $self->{DEV_TYPE} = shift || "B"; bless($self,$class); return $self; } sub b_func{ print "This is B func\n"; } 1;
C.pm:
package C; use Carp qw (croak); use strict; use warnings; eval "use A"; die $@ if $@; eval "use B"; die $@ if $@; our @ISA = ("A","B"); sub new { my $class = shift; my $self = $class->SUPER::new(@_); print "This is C new\n"; $self->{DEV_TYPE} = shift || "C"; bless($self,$class); return $self; } sub c_func{ print "This is C func\n"; } 1;
在C :: new中,$class-> SUPER :: new不会调用B的构造函数.如果我用$class-> B :: new(@_);显式调用它,我得到错误
Can’t locate object method “new” via package “B” at C.pm
我究竟做错了什么?
解决方法
When a class has multiple parents,the method lookup order becomes more complicated.
By default,Perl does a depth-first left-to-right search for a method. That means it starts with the first parent in the
@ISA
array,and then searches all of its parents,grandparents,etc. If it fails to find the method,it then goes to the next parent in the original class’s@ISA
array and searches from there.
这意味着$class-> SUPER :: new只会调用其中一个父构造函数.如果您需要从子类运行两个父类中的初始化逻辑,请将其移动到单独的方法中,如this post中所述.
当您使用$class-> B :: new显式调用B :: new时,您会得到
Can’t locate object method “new” via package “B” at C.pm
因为使用B正在加载core module B而不是你的模块.您应该重命名您的模块.
请注意,最好使用parent
编译指示而不是手动设置@ISA,例如
use parent qw(Parent1 Parent2);
parent负责加载父模块,因此你可以删除相关的use语句(顺便说一下,你不应该使用它来进行评估).