2013-10-27 3 views
3

Есть:Правильный способ определить и преобразовать тип атрибута Муз

package MyPath; 
use strict; 
use warnings; 
use Moose; 

has 'path' => (
    is => 'ro', 
    isa => 'Path::Class::Dir', 
    required => 1, 
); 
1; 

Но хочу создать этот объект с двумя способами, например:

use strict; 
use warnings; 
use MyPath; 
use Path::Class; 
my $o1 = MyPath->new(path => dir('/string/path')); #as Path::Class::Dir 
my $o2 = MyPath->new(path => '/string/path'); #as string (dies - on attr type) 

И когда называют это с «Str» - хотение преобразуйте его внутри пакета MyPath в Class :: Path :: Dir, поэтому оба: $o1->path и $o2->path должны возвращаться блаженным Path::Class::Dir

Когда я попытался расширить определение ition к следующему:

has 'path' => (
    is => 'ro', 
    isa => 'Path::Class::Dir|Str', #allowing both attr types 
    required => 1, 
); 

Он не работает и до сих пор нужно «несколько» преобразовать Str в Path::Class::Dir автоматически, внутренне в package MyPath ...

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

EDIT: На основе намека Oesor я обнаружил, чем мне нужно коснуться как:

coerce Directory, 
    from Str,  via { Path::Class::Dir->new($_) }; 

has 'path' => (
    is => 'ro', 
    isa => 'Directory', 
    required => 1, 
); 

Но до сих пор нету идеи, как правильно использовать его ...

еще несколько советов, пожалуйста?

ответ

5

Вы ищете типа приводки.

use Moose; 
use Moose::Util::TypeConstraints; 
use Path::Class::Dir; 

subtype 'Path::Class::Dir', 
    as 'Object', 
    where { $_->isa('Path::Class::Dir') }; 

coerce 'Path::Class::Dir', 
    from 'Str', 
     via { Path::Class::Dir->new($_) }; 

has 'path' => (
    is  => 'ro', 
    isa  => 'Path::Class::Dir', 
    required => 1, 
    coerce => 1, 
); 
+0

спасибо - отлично работает. – novacik

+1

Ваше объявление «подтип» Path :: Class :: Dir '... 'может быть написано более естественно как« class_type »Path :: Class :: Dir';'. – hobbs

0

Подсказка - ищите, как заставить значение:

https://metacpan.org/pod/Moose::Manual::Types

+0

Не могли бы вы добавить еще несколько советов? Я отредактировал мой вопрос ... (Возможно, понадобилось еще 1-2 строки - не могли бы вы дать мне ответ? :) – novacik