散列表是Perl對象的典型初始值設定項。現在你的輸入是不可靠的,因爲你不知道對於任何給定的鍵是否會有一個定義的值,也不知道密鑰是否存在。現在你想把這種不可靠的輸入提供給Moose對象,而缺少的鍵完全沒問題,你確實想擺脫未定義的值,所以你最終不會得到一個充滿未定義屬性的對象。使Moose構造函數忽略undef參數
當實例化對象並過濾出未定義的值時,您當然可以非常小心。但是讓我們假設你想在你的構造函數中安裝這個過濾器,因爲它在一個地方。你希望構造函數忽略未定義的值,但不會在遇到它們時死掉。
對於存取方法,您可以使用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;
閱讀[Moose :: Cookbook](http://search.cpan.org/perldoc/Moose::Cookbook)。特別是[Moose :: Cookbook :: Basics :: Recipe10](http://search.cpan.org/perldoc/Moose::Cookbook::Basics::Recipe10)。 – 2011-04-28 19:29:56