2016-03-25 7 views
3

У меня есть пользовательский типа DateTime, который имеет принуждение, определенное на ней из строки в DateTime, например так:Выполнить принуждения внутри пользовательского ограничения Type :: Tiny?

package Library; 
use Type::Library -base, -declare => qw(DateTime); 
use DateTime::Format::ISO8601; 

class_type DateTime, { class => 'DateTime' }; 

coerce DateTime, from Str, via { DateTime::Format::ISO8601->parse_datetime($_) }; 

я хотел бы использовать этот тип DateTime в Словаре, например, так:

package MyObj; 
use Moo; 
$constraint = declare MyType, as Dict[ name => Str, date => DateTime ]; 

has 'whatsis' => (is => 'ro', isa => $constraint); 

а потом называют его:

use MyObj; 
my $obj = MyObj->new(whatsis => { name => 'Something', date => '2016-01-01' }); 

Я попытался добавить coerce => 1 к объявлению whatsis, но это не помогло.

Как создать собственный тип, который наследуется от Dict, и запускает типы ограничений, определенных в типах членов?

ответ

1

С большим количеством помощи от https://metacpan.org/pod/distribution/Type-Tiny/lib/Type/Tiny/Manual/Coercions.pod

Library.pm:

package Library; 
use Type::Library -base, -declare => qw(Datetime); 
use Type::Utils -all; 
use Types::Standard -all; 
use DateTime::Format::ISO8601; 

class_type Datetime, { class => 'DateTime' }; 
coerce Datetime, 
    from Str, via { DateTime::Format::ISO8601->parse_datetime($_) }; 

declare 'MyType', as Dict[ name => Str, date => Datetime ], coercion => 1; 

MyObj.pm:

package MyObj; 
use Moo; 
use Library -all; 

has 'whatsis' => (is => 'ro', isa => MyType, coerce => 1); 

tester.pl:

#!perl 
use MyObj; 
my $obj = MyObj->new(whatsis => { name => 'Something', date => '2016-01-01' }); 
use Data::Dumper; print Dumper $obj;