爲什麼不將該屬性的定義移動到一個角色中,並在其他類中重用它,並將其與 適當的參數化重用?
package MyApp::Thingy::HasPeople;
use MooseX::Role::Parameterized;
parameter person_type => (
isa => 'Str',
required => 1,
);
role {
my $person_type = shift->person_type;
has 'people' => (
is => 'ro',
isa => "ArrayRef[${person_type}]",
traits => ['Array'],
default => sub { [] },
handles => {
all_people => 'elements',
get_people => 'get',
push_people => 'push',
pop_people => 'pop',
count_people => 'count',
sort_people => 'sort',
grep_people => 'grep',
},
);
};
1;
和其他地方,在真正需要的是屬性
package MyApp::Thingy::WithChildren;
use Moose;
with 'MyApp::Thingy::HasPeople' => { person_type => 'Person::Child' };
1;
或
package MyApp::Thingy::WithAdults;
use Moose;
with 'MyApp::Thingy::HasPeople' => { person_type => 'Person::Adult' };
1;
這樣,你得到這兩個在兩個地方無法維持的屬性,並獲得了類結束 與相同的類但不同的API的對象,這往往是一個很大的代碼氣味。
或者,你可以簡單地寫ArrayRef
亞型接受無論是要麼Person::Child
或Person::Adult
或任何其他類型的你的人的名單,但只只要該列表中的所有元素都是相同類型的。
use List::AllUtils 'all';
subtype 'PersonList', as 'ArrayRef', where {
my $class = blessed $_->[0];
$_->[0]->isa('Person') && all { blessed $_ eq $class } @{ $_ };
};
has persons => (
is => 'ro',
isa => 'PersonList',
...,
);
我可能會去的第一個解決方案,以便能夠決定基於一個對象類,如果它包含兒童,成年人,或什麼的。
您是否需要比'ArrayRef [Any]'更多的輸入控件? – 2010-11-12 18:33:22