加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

type-conversion – Perl6类属性中的类型强制

发布时间:2020-12-16 06:25:41 所属栏目:大数据 来源:网络整理
导读:与Perl5中的大多数内容一样,有许多方法可以创建支持其属性的自定义类型强制的类.这是一个简单的,从数组引用到哈希: #!/usr/bin/env perlpackage Local::Class { use Moo; use Types::Standard qw( HashRef ArrayRef ); has set = ( is = 'ro',coerce = 1,is
与Perl5中的大多数内容一样,有许多方法可以创建支持其属性的自定义类型强制的类.这是一个简单的,从数组引用到哈希:

#!/usr/bin/env perl

package Local::Class {
  use Moo;
  use Types::Standard qw( HashRef ArrayRef );

  has set => (
    is => 'ro',coerce => 1,isa => HashRef->plus_coercions(
      ArrayRef,sub { return { map { $_ => 1} @{$_[0]} } },),);
}

my $o = Local::Class->new({ set => [qw( a b b c )] });
# $o->set now holds { a => 1,b => 1,c => 1}

我一直在尝试将这样的东西移植到Perl6,在我看来我需要的是一种将数组强制转换为SetHash的方法.到目前为止,我能够做到这一点的唯一方法是:

#!/usr/bin/env perl6

class Local::Class {
  has %.set;
  ## Wanted to have
  # has %.set is SetHash;
  ## but it dies with "Cannot modify an immutable SetHash"

  submethod TWEAK (:$set) {
    self.set = $set.SetHash;
  }
}

my $o = Local::Class.new( set => [< a b b c >] );
# $o.set now holds {:a,:b,:c}

但是在我看来这不是正确的方法,至少对于将奇数编号列表传递给构造函数的微小细节会使脚本死亡.

那么,这是如何在Perl6中完成的?有什么建议的方法(因为我确定不止一个)为类属性实现自定义类型强制?

解决方法

TWEAK在BUILD初始化对象之后运行,这就是提供奇数编号阵列会爆炸的地方.

将强制移动到BUILD时间,事情应按预期工作:

class Local::Class {
  has %.set;
  submethod BUILD (:$set) {
    %!set := $set.SetHash;
  }
}

如果您可以将强制SetHash()参数类型与自动属性初始化结合使用会很好,但这会失败,因为sigil是属性名称的一部分,如果您想接受非参数,则参数不能为%-sigilled – 关联类型.

但是,如果您使用$-sigilled属性,它可以正常工作:

class Local::Class {
  has $.set;
  submethod BUILD (SetHash() :$!set) {}
}

正如@smls指出的那样,以下变种

class Local::Class {
  has %.set is SetHash;
  submethod BUILD (:$set) {
    %!set = $set.SetHash;
  }
}

可能应该工作,而不是死亡无法修改不可变的SetHash.

作为SetHash无法分配的解决方法,您可以使用

class Local::Class {
  has %.set is SetHash;
  submethod BUILD (:$set) {
    %!set{$set.SetHash.keys} = True xx *;
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读