2013-12-07 2 views
0

нужно сделать что-то вроде следующих (и более):Moose атрибутов - прием несколько модулей с общим родителем

my $val1 = My::Module::Type1->new(...); 
my $val2 = My::Module::Type2->new(...); 

my $some = Some->new(val => [$val1, $val2]); 

Как определить $val в Some упаковке (Moose основе)? Так,

package Some; 
use Moose; 
has 'val' => (
    isa => 'ArrayRef[My::Module::__ANYTHING__HERE__]', # <-- here is the problem 
); 

Проблема состоит в том, чем сейчас есть только My::Module::Type1, но как построить Some->val для принятия любого будущего My::Module::_something_?

Моя лучшая идея состоит в том

use Moose; 
use Moose::Util::TypeConstraints; 
usa Scalar::Util qw(blessed); 

subtype MySubModule, 
    as Object => where { 
     blessed $_ =~ /^My::Module/ 
    }, 
    message { "Need My::Module class" }; 

has val => (is => 'rw', isa => 'ArrayRef[MySubModule]'); 

Но я не думаю, чем это лучший способ, потому что, если кто-то делает Your::Module, что будет подкласс My::Module?

Может ли кто-нибудь посоветовать мне что-то более правильное решение?

(Возможно, потребуется несколько включать роли, (или черт), но (честно) - до сих пор никогда не использовали любую роль - и не знает, как использовать их ..;()

Я надеюсь, что вышеупомянутым понятно - к сожалению, мой английский плохо, как точно также мой Perl ..;. (

+1

Являются ли эти все подклассы «My :: Module»? Потому что, если они есть, проверка 'isa' - это все, что вам нужно. – friedo

ответ

1

Используйте тип ограничение класса Он уважает наследство ...

use Moose; 
use Moose::Util::TypeConstraints; 

class_type 'MyModule', { class => 'My::Module' }; 

has val => (is => 'rw', isa => 'ArrayRef[MyModule]'); 

Или лучше (хотя имейте в виду, я предвзято) ...

use Moose; 
use Types::Standard -types; 

has val => (is => 'rw', isa => ArrayRef[InstanceOf['My::Module']]);