现在有:
has 'id' => ( is => 'rw',isa => 'Str',default => sub { "id" . int(rand(1000))+1 } );
工作正常,:
PKG->new(id => 'some'); #the id is "some" PKG->new() #the id is #id<random_number>
在下一个场景中:
my $value = undef; PKG->new(id => $value);
(当然)有一个错误:
Attribute (id) does not pass the type constraint because: Validation Failed for 'Str' with value undef at /Users/me/perl5/perlbrew/perls/perl-5.16.3/lib/site_perl/5.16.3/darwin-thread-multi-2level/Moose/Exception.pm line 37
问题是:
如何在设置为undef之后更改值(并且仅当它是$undef时)?所以,
has 'id' => ( is => 'rw',isa => 'Str|Undef',#added undef to acceptable Type default => sub { "id" . int(rand(1000))+1 } );
现在,它接受了$undef,但我不想要$undef但是想要“id”. int(rand(1000))1.如何在设置后更改属性值?
after仅针对不是构造函数的访问器调用.也许是从Undef到Str的一些奇怪的强制 – 但仅限于这一属性?
Ps:使用PKG-> new(id => $value // int(rand(10000)))不是可接受的解决方案.该模块应接受$undef,并应默默地将其更改为随机数.
解决方法
Type::Tiny的目标之一是轻松地将强制添加到个人属性中.这是一个例子:
use strict; use warnings; { package Local::Test; use Moose; use Types::Standard qw( Str Undef ); my $_id_default = sub { "id" . int(rand(1000)+1) }; has id => ( is => 'rw',isa => Str->plus_coercions(Undef,$_id_default),default => $_id_default,coerce => 1,); __PACKAGE__->Meta->make_immutable; } print Local::Test->new(id => 'xyz123')->dump; print Local::Test->new(id => undef)->dump; print Local::Test->new->dump;
您还可以查看MooseX::UndefTolerant,它会将undef值传递给构造函数,就好像它们被完全省略一样.这不会涵盖将undef传递给访问者;只是构造者.