Я получил много исключений из QA из-за неполных данных, передаваемых моим конструкторам Moose. Имя атрибута присутствует в аргументах конструктора, но значение равно undef
.
Это факт жизни со многими приложениями сценариев, что вещи просто undef
. И часто это прекрасно. Вы не хотите назойливое предупреждение от warnings
прагмы (поэтому вы делаете no warnings 'uninitialized'
), и вы, конечно, не хотите, чтобы ваш код умер, потому что одно маленькое значение, скажем, housenumber, равно undef
.
Так что без лишних слов я хочу, чтобы мои конструкторы Moose вели себя как прямой Perl (т.е. без use warnings 'uninitialized'
), то есть для преобразования undef
в 0
или пустой строки, как требуется. Попытка, показанная в этом примере, не работает для случая, когда присутствует имя атрибута, но значение равно undef
. Я мог бы подумать об использовании BUILDARGS
для достижения того, чего я хочу. Но существует ли декларативный способ в обычном Moose без обращения к MooseX :: UndefTolerant (который, к сожалению, я не могу использовать, поскольку он не установлен)?
package AAA;
use Moose;
has 'hu', is => 'ro', isa => 'Str';
has 'ba', is => 'ro', isa => 'Int';
no Moose; __PACKAGE__->meta->make_immutable;
package BBB;
use Moose; extends 'AAA';
has '+hu', default => ''; # don't want to die on undef
has '+ba', default => 0; # idem
no Moose; __PACKAGE__->meta->make_immutable;
package main;
use Test::More;
use Test::Exception;
# Those AAAs should die ...
throws_ok { AAA->new( hu => undef ) }
qr/Validation failed for 'Str' with value undef/;
throws_ok { AAA->new( ba => undef ) }
qr/Validation failed for 'Int' with value undef/;
# .. but these BBBs should live:
lives_ok { BBB->new( hu => undef ) } 'hu supplied as undef';
lives_ok { BBB->new( ba => undef ) } 'ba supplied as undef';
done_testing;