由于质量不完整的数据被馈送到Moose构造函数,我从质量检查部门收到了的异常。属性名称存在于构造函数参数中,但值为undef
。
对于许多脚本应用程序来说,事实只是undef
而已,这是事实。通常,这是完全可以的。您不希望warnings
编译指示发出烦人的警告(因此您执行no warnings 'uninitialized'
),并且您当然不希望您的代码消失,因为一个小值(例如,门牌号)就是undef
。
因此,事不宜迟,我希望我的Moose构造函数的行为像直接的Perl(即没有use warnings 'uninitialized'
)一样,即根据需要将undef
转换为0
或空字符串。此示例中显示的尝试不适用于存在属性名称但值为undef
的情况。我可以考虑使用BUILDARGS
实现我想要的。但是,在没有resorting to 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;
最佳答案
在Moose::Manual::Types中记录了一种处理此类问题的方法。
使用Maybe[a]
类型。
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', is => 'rw', isa => 'Maybe[Str]', default => ''; # will not die on undef
has 'ba', is => 'rw', isa => 'Maybe[Int]', default => 0; # idem
sub BUILD {
my $self = shift;
$self->hu('') unless defined $self->hu;
$self->ba(0) unless defined $self->ba;
}
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';
my $bbb = BBB->new( hu => undef, ba => undef );
is $bbb->hu, '', "hu is ''";
is $bbb->ba, 0, 'ba is 0';
done_testing;
关于perl - 驼鹿(Perl): convert undef to empty string or 0 rather than die(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6457825/