由于质量不完整的数据被馈送到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/

10-10 18:57