perl – 懒惰属性强制
发布时间:2020-12-15 23:32:05 所属栏目:大数据 来源:网络整理
导读:使用 Moose,您可以在属性上使用惰性构建器,如果尚未填充属性,则首次访问属性时将调用构建器.您可以使用强制对属性进行类型强制,但只要设置了属性,就会应用此属性,因此即使在对象初始化时也是如此. 我正在寻找一种实现延迟强制的方法,其中一个属性可能最初被
使用
Moose,您可以在属性上使用惰性构建器,如果尚未填充属性,则首次访问属性时将调用构建器.您可以使用强制对属性进行类型强制,但只要设置了属性,就会应用此属性,因此即使在对象初始化时也是如此.
我正在寻找一种实现延迟强制的方法,其中一个属性可能最初被填充,但只有在首次访问时才被强制执行.当胁迫很昂贵时,这很重要. 在下面的示例中,我使用union类型和方法修饰符来执行此操作: package My::Foo; use Moose; has x => ( is => 'rw',isa => 'ArrayRef | Int',required => 1 ); around "x" => sub { my $orig = shift; my $self = shift; my $val = $self->$orig(@_); unless(ref($val)) { # Do the cocerion $val = [ map { 1 } 1..$val ]; sleep(1); # in my case this is expensive } return $val; }; 1; my $foo = My::Foo->new( x => 4 ); is_deeply $foo->x,[ 1,1,1 ],"x converted from int to array at call time"; 但是这有一些问题: >我不喜欢union类型方法修饰符方法.这与use coercion instead of unions的“最佳实践”建议背道而驰.这不是声明性的. 更新: package My::ArrayFromInt; use Moose; use Moose::Util::TypeConstraints; subtype 'My::ArrayFromInt::Inner',as 'ArrayRef[Int]'; coerce 'My::ArrayFromInt::Inner',from 'Int',via { return [ (1) x $_ ] }; has uncoerced => (is => 'rw',isa => 'Any',required => 1); has value => ( is => 'rw',isa => 'My::ArrayFromInt::Inner',builder => '_buildValue',lazy => 1,coerce => 1 ); sub _buildValue { my ($self) = @_; return $self->uncoerced; } 1; package My::Foo; use Moose; use Moose::Util::TypeConstraints; subtype 'My::ArrayFromInt::Lazy' => as class_type('My::ArrayFromInt'); coerce 'My::ArrayFromInt::Lazy',via { My::ArrayFromInt->new( uncoerced => $_ ) }; has x => ( is => 'rw',isa => 'My::ArrayFromInt::Lazy',required => 1,coerce => 1 ); 1; 如果调用$foo-> x->值,则此方法有效.但是这并没有解决第2点,因为我需要为我想要转换的每个属性创建My :: ArrayFromInt和:: Lazy子类型.如果可能的话,我想避免调用$foo-> x->值. 解决方法
怎么样的typedef沿着描述的线,然后做
has _x => ( is => 'ro',isa => 'Int|MyArrayOfInts',init_arg => 'x',); has x => ( is => 'ro',lazy => 1,isa => 'MyArrayOfInts',coerce => 1,default => sub { $_[0]->_x },); 将它包装成某种辅助方法以沿着线条创建一对对象是有意义的 has_lazily_coerced x => ( is => 'ro',isa => 'TargetType',); 它会反省TargetType以获取未强制阴影属性的合法类型列表,并为您生成一对属性. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |