a
和A
中定义的方法A::B
。
C
源自A
并使用A::B
。
问题1 :为什么A::B->a
覆盖A->a
?
$ perl x.pl
b
问题2 :如果我们将A::B->a
添加到C->a
,为什么sub a {'c'}
不会覆盖C
?
A.pm :基类
package A;
use Moose;
sub a {
return 'a';
}
no Moose;
1;
A / B.pm :角色
package A::B;
use Moose::Role;
sub a {
return 'b';
}
1;
C.pm :从A派生的角色为A :: B
的类package C;
use Moose;
extends "A";
with "A::B";
no Moose;
1;
bin.pl
use v5.10;
use strict;
use warnings;
use C;
my $c = C->new();
say $c->a;
答案 0 :(得分:6)
package C;
use Moose;
extends 'A';
使包C
成为A
的子类。在幕后,它将A
添加到@C::ISA
。当类型C
的对象调用方法并且在命名空间C
中找不到方法名称时,perl将检查@C::ISA
中的命名空间以查找解析方法名称的方法。
package C;
use Moose;
with 'A::B';
做了不同的事情。它不会使C
成为A::B
的子类。它将条目从A::B
命名空间复制到C
命名空间。
因此,当您致电$c->a
时,Perl会找到一个子例程&C::a
,因为它是从&A::B::a
复制的,这就是它所使用的内容。它不需要遍历@C::ISA
来搜索另一个名为a
的子例程。
如果您还在sub a { ... }
中定义了package C
,那么use Moose ... with 'A::B'
将不会覆盖它。