2010-11-12 26 views
3

我有一個具有以下屬性的駝鹿對象:我可以在施工時設置駝鹿對象屬性的'isa'嗎?

has 'people' => (
is  => 'ro', 
isa  => 'ArrayRef[Person::Child]', 
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', 
}, 
); 

注意isa被設置爲「數組引用[人物::兒童]」。

我希望能夠在創建我的對象時在Person::Child,Person::Adult等之間進行選擇。這是可能的還是必須創建不同的對象,除people屬性的isa之外其他對象相同?

(這讓我想起了Java generics)。

+1

您是否需要比'ArrayRef [Any]'更多的輸入控件? – 2010-11-12 18:33:22

回答

5

爲什麼不將該屬性的定義移動到一個角色中,並在其他類中重用它,並將其與 適當的參數化重用?

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::ChildPerson::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', 
    ..., 
); 

我可能會去的第一個解決方案,以便能夠決定基於一個對象類,如果它包含兒童,成年人,或什麼的。

+0

我們;;我試圖避免明確創建多個類。 – 2010-11-14 12:49:50

+1

爲什麼?我看不出每堂課只有一行的危害。如果它困擾你實際上寫下它們 - 使用MOP爲你建立它們。 – rafl 2010-11-14 13:49:39

相關問題