perl – 懒惰属性强制

perl – 懒惰属性强制,第1张

概述使用 Moose,您可以在属性上使用惰性构建器,如果尚未填充属性,则首次访问属性时将调用构建器.您可以使用强制对属性进行类型强制,但只要设置了属性,就会应用此属性,因此即使在对象初始化时也是如此. 我正在寻找一种实现延迟强制的方法,其中一个属性可能最初被填充,但只有在首次访问时才被强制执行.当胁迫很昂贵时,这很重要. 在下面的示例中,我使用union类型和方法修饰符来执行此 *** 作: package 使用 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的“最佳实践”建议背道而驰.这不是声明性的.
>我需要在许多类中使用许多属性来执行此 *** 作.因此需要某种形式的DRY.这可能是元属性角色,类型强制,你有什么.

更新:
我遵循ikegami’s建议将昂贵的类型强制封装在一个对象内,并为这个对象提供外部强制:

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以获取未强制阴影属性的合法类型列表,并为您生成一对属性.

总结

以上是内存溢出为你收集整理的perl – 懒惰属性强制全部内容,希望文章能够帮你解决perl – 懒惰属性强制所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1269268.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存