The method a
defined in both A
and in A::B
.
C
is derived from A
and uses A::B
.
Question 1: Why A::B->a
override A->a
?
$ perl x.pl
b
Question 2: Why A::B->a
wouldn't override C->a
, if we add sub a {'c'}
into C
?
A.pm: base class
package A;
use Moose;
sub a {
return 'a';
}
no Moose;
1;
A/B.pm: a role
package A::B;
use Moose::Role;
sub a {
return 'b';
}
1;
C.pm: a class derived from A with the role 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;
package C;
use Moose;
extends 'A';
makes package C
a subclass of A
. Behind the scenes, it adds A
to @C::ISA
. When an object of type C
calls a method and the method name is not found in namespace C
, perl will inspect the namespaces in @C::ISA
to look for a way to resolve the method name.
package C;
use Moose;
with 'A::B';
does something different. It does not make C
a subclass of A::B
. It copies entries from the A::B
namespace into the C
namespace.
So when you call $c->a
, Perl finds a subroutine &C::a
because it was copied from &A::B::a
, and that's what it uses. It does not need to walk through @C::ISA
to search for another subroutine named a
.
If you also define a sub a { ... }
in package C
, then use Moose ... with 'A::B'
will not overwrite it.