Let's say I have a class Foo
with plugin traits/roles Bar
and Baz
, where Baz
is dependent on Bar
.
package Foo;
use Moose;
with 'MooseX::Traits';
sub foo {print "foo\n"}
package Bar;
use Moose::Role;
sub bar {
shift->foo;
print "bar\n";
}
package Baz;
use Moose::Role;
requires 'bar';
sub baz {
shift->bar;
print "baz\n";
}
package main;
my $foo = Foo->new_with_traits( traits => [qw/Bar Baz/] );
$foo->baz;
In this example, I've enforced the dependency with requires 'bar'
. However, what I want to do is for Baz
to require the ent开发者_高级运维ire role Bar
to enforce the dependency between the plugins.
Is there a simple way I can do this? Or do you have a suggestion for an alternative approach?
It makes sense to do it the way you have already demonstrated. This is because the attributes and methods that a role provides should be enough to make it compatible with your interface.
If you were to depend on specific roles by name then you would not for instance be able to provide a polymorphic role with a different package name, whereas if you depend on certain attributes being available through the interface then you can.
Everything cubabit said is true. It's better to enforce a reliance upon an API rather than a specific Implmentation or Type. However to answer your specific question the way you would tie Baz
to require Bar
is to simply have it compose Bar
itself.
package Baz {
use Moose::Role;
with qw(Bar);
...
}
Then you would simply use Baz
alone when you composed it with Foo
at runtime.
my $foo = Foo->with_traits('Baz')->new(...);
$foo
then does()
both Baz
and Bar
.
精彩评论