Thanks choroba, I didn't know about those Role::Tiny methods.
I am not sure about whether I prefer them to eval "with '$module'; 1;", though.
I had to load Role::Tiny explicitly not importing anything, since its before(), after(), around() and with() methods clash with Moo's :
Subroutine MyClass::before redefined at [...]/5.22.0/Role/Tiny.pm line
+ 58.
Subroutine MyClass::after redefined at [...]/5.22.0/Role/Tiny.pm line
+58.
Subroutine MyClass::around redefined at [...]/5.22.0/Role/Tiny.pm line
+ 58.
Subroutine MyClass::with redefined at [...]/5.22.0/Role/Tiny.pm line 6
+7.
And even when I do that I can't use apply_roles_to_object() inside sub BUILD, because the parent's methods haven't been loaded and thus the child's will be.
package MyClass::Child;
use Moo::Role;
sub foo { die 'horribly'; }
sub bar { return 'bar'; }
1;
package MyClass;
use Moo;
use Role::Tiny();
sub BUILD {
my $self = shift;
Role::Tiny->apply_roles_to_object( $self, 'MyClass::Child' );
return $self;
};
sub foo { return 'foo'; }
1;
Output:
$ perl -MMyClass -E '$o = MyClass->new; say $o->foo, $o->bar;'
horribly at MyClass/Child.pm line 5.
So the only way I could make it work as part of the Moo constructor was with apply_roles_to_package() :
package MyClass;
use Moo;
use Role::Tiny();
sub BUILD {
my $self = shift;
Role::Tiny->apply_roles_to_package( __PACKAGE__, 'MyClass::Child'
+);
return $self;
};
sub foo { return 'foo'; }
1;
Output:
$ perl -MMyClass -E '$o = MyClass->new; say $o->foo, $o->bar;'
foobar
Thanks again for the pointer.
The way forward always starts with a minimal test.
|