複数のロールがあり、それぞれが一連のアイテムを定義しているとします。
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(B C);
sub do_something {
my $self = shift;
my @items = ???; # How can I get apple, orange, watermelon, banana here?
....
}
考えられる解決策の 1 つはMooseX::ComposedBehaviorを採用することですが、その POD は (もちろん、執筆時点では) その API は「完全に安定していない」と述べており、「現在の実装はハックのようなものであり、置き換える必要がある」とも述べています。より堅牢なものによって」。そのため、このような「ハック」に頼らずにこれを達成できるかどうかを調査しています。
警告:今後これを読む場合は、MooseX::ComposedBehavior (現在のバージョン: 0.003) の POD を確認してください。その間に変更されている可能性があります。物事は急速に変化します。CPAN の作成者は新しいバージョンをリリースします。現時点で「安定していない」ものは、将来的にはより安定する可能性があります。他のモジュールがあるかもしれません。自分自身で調べて。
理想的には、次のようなものがあるはずです:my @items = map $_->items, @ISA;
ただし、Moose では機能しません。より優れた信頼性の高いソリューションはありますか?
更新:私はこの3行の解決策になりました:
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(B C);
sub items () {}
sub do_something {
my $self = shift;
my @items = map $_->execute, grep $_,
map $_->get_method('items'),
$self->meta->calculate_all_roles_with_inheritance;
...
}
更新: #moose IRC チャンネルでさまざまな人からリクエストがあったため、MooseX::ComposedBehavior は「安定していない」という以前の主張を削除し、POD から取得したリテラル テキストに置き換えました。
更新:次の構文を使用できる MooseX::Collect モジュールを作成しました。
package Foo;
use Moose;
use MooseX::Collect;
collect 'items';
with qw(B C);
sub do_something {
my $self = shift;
my @items = $self->items;
...
}