Suppose I have several roles, each of which defines a set of elements:
package A; use Moose::Role; sub items () { qw/apple orange/ } package B; use Moose::Role; with 'A'; sub items () { qw/watermelon/ } package C; use Moose::Role; sub items () { qw/banana/ }
Suppose I use them in another class and I want to collect all these elements:
package Foo; use Moose; with qw(BC); sub do_something { my $self = shift; my @items = ???;
One possible solution is to take MooseX :: ComposedBehavior , but its POD says (at the time of writing, of course) that its API is "not completely stable" and that "the current implementation is a bit of a hack and needs to be replaced with a more reliable one " Thus, I am exploring whether this can be done without relying on such a โhackโ.
Warning: if you are reading this in the future, go to check POD MooseX :: ComposedBehavior (current version: 0.003) because it could be changed on average. Things are changing fast. CPAN authors release new versions. That which is "not entirely stable" at the moment may become more stable in the future. There may be other modules. Check yourself.
Ideally, it should be something like: my @items = map $_->items, @ISA; However, this is not with Mus. Are there any more reliable and reliable solutions?
Update: I finished this three-line solution:
package A; use Moose::Role; sub items () { qw/apple orange/ } package B; use Moose::Role; with 'A'; sub items () { qw/watermelon/ } package C; use Moose::Role; sub items () { qw/banana/ } package Foo; use Moose; with qw(BC); sub items () {} sub do_something { my $self = shift; my @items = map $_->execute, grep $_, map $_->get_method('items'), $self->meta->calculate_all_roles_with_inheritance; ... }
Update:. As various people asked me on the # moose IRC channel , I removed my previous statement that MooseX :: ComposedBehavior is โunstableโ and replaced it with literal text taken from its POD.
Update: I wrote a MooseX :: Collect module that allows you to use the following syntax:
package Foo; use Moose; use MooseX::Collect; collect 'items'; with qw(BC); sub do_something { my $self = shift; my @items = $self->items; ... }