【发布时间】:2014-09-20 00:04:56
【问题描述】:
哈希表是 Perl 对象的典型初始化器。现在你的输入是不可靠的,因为你不知道任何给定的键是否会有一个定义的值,也不知道键是否存在。现在您想将这种不可靠的输入提供给 Moose 对象,虽然缺少键完全可以,但您确实希望摆脱未定义的值,这样您就不会得到一个充满未定义属性的对象。
在实例化对象并过滤掉未定义的值时,您当然可以非常小心。但是假设你想在你的构造函数中安装那个过滤器,因为它就在一个地方。您希望构造函数忽略未定义的值,但不要因为遇到它们而死。
对于访问器方法,可以使用around左右来防止属性被设置为undef。但是那些method modifiers 不是为构造函数调用的,只是为访问器调用的。 Moose 中是否有类似的工具可以为 c'tor 实现相同的效果,即排除任何 undef 属性被接受?
请注意,如果属性为 undef,Moose Any 类型将在对象中创建哈希键。我不希望这样,因为我希望 %$self 不包含任何 undef 值。
这是我做的一些测试:
package Gurke;
use Moose;
use Data::Dumper;
has color => is => 'rw', isa => 'Str', default => 'green';
has length => is => 'rw', isa => 'Num';
has appeal => is => 'rw', isa => 'Any';
around color => sub {
# print STDERR Dumper \@_;
my $orig = shift;
my $self = shift;
return $self->$orig unless @_;
return unless defined $_[0];
return $self->$orig( @_ );
};
package main;
use Test::More;
use Test::Exception;
my $gu = Gurke->new;
isa_ok $gu, 'Gurke';
diag explain $gu;
ok ! exists $gu->{length}, 'attribute not passed, so not set';
diag q(attempt to set color to undef - we don't want it to succeed);
ok ! defined $gu->color( undef ), 'returns undef';
is $gu->color, 'green', 'value unchanged';
diag q(passing undef in the constructor will make it die);
dies_ok { Gurke->new( color => undef ) }
'around does not work for the constructor!';
lives_ok { $gu = Gurke->new( appeal => undef ) } 'anything goes';
diag explain $gu;
diag q(... but creates the undef hash key, which is not what I want);
done_testing;
【问题讨论】: