Object Perl 6-是否可以创建一个属性trait来设置元属性?

Object Perl 6-是否可以创建一个属性trait来设置元属性?,object,attributes,immutability,traits,raku,Object,Attributes,Immutability,Traits,Raku,我尝试创建一个属性特征。用例是在对象到文档映射的上下文中将类的某些属性标记为可修改,而其他属性则不可修改 role crud { has Bool $.crud is default(True); } multi trait_mod:<is>(Attribute $a, crud, $arg) { $a.container.VAR does crud($arg); } class Foo { has $.bar is rw; # Provide

我尝试创建一个属性特征。用例是在对象到文档映射的上下文中将类的某些属性标记为可修改,而其他属性则不可修改

role crud {
    has Bool $.crud is default(True);
}

multi trait_mod:<is>(Attribute $a, crud, $arg) {
    $a.container.VAR does crud($arg);
}

class Foo {
    has $.bar is rw;

    # Provide an extra nested information
    has $.baz is rw is crud(True);
}
我从中了解到,$.baz属性得到了我所称的元属性,它独立于它的潜在值

如果我正确地理解了我在这里所做的事情,并且我所使用的特性不是一个肮脏的黑客行为,那么对我来说这看起来很好。有可能达到$foo.baz.crud,这是事实。不过,我不太明白.Scalar+{crud}是什么意思,我是否可以在那里设置一些东西,以及如何设置

当我尝试设置$.baz实例属性时,返回以下错误:

Cannot modify an immutable Scalar+{crud} (Scalar+{crud}.new(crud => Bool::True))
  in block <unit> at t/08-attribute-trait.t line 30

我是在尝试做一些不可能的事情吗?如何调整此代码以实现此用例?

这里有几个方面。首先,trait_mod的签名看起来是错误的。第二,当一个特征的名称与一个现有角色的名称相同时,就会出现不良的交互作用。我相信这应该是一个NYI异常,但显然它要么在解析时出错,要么在试图生成错误消息时出错

无论如何,我想这就是你想要的:

角色CRUD{};因为CRUD是作为首字母缩略词使用的,所以我选择在这里使用大写 多特征_mod:Attribute:D$a,:$crud!{注意需要命名属性! $a.^mixin:CRUD如果是$CRUD;如果给定了真值,则在CRUD角色中混合 } 甲级{ has$.a是crudFalse;太糟糕了!crud是无效语法 有美元。b是积垢; } 对A.^attributes;$说$\.name:{$\~~CRUD}!a:错,$!b:是的
希望这有帮助。

如果crud不接受参数,您能解释一下crud$arg的作用吗?或者,考虑到它看起来像是伪造的代码,考虑到你说它与你在这个问题上的关注点无关,那么就把它删掉吧?换句话说,把最后一段代码作为问题的核心,把第一段代码扔掉。这有意义吗?哦!考虑到忽略$arg问题的简化版本,我突然觉得您只是在尝试扮演什么角色crud{};类Foo{has$。baz是rw是crud};说Foo.new.baz~~crud;True应该做的事情,而不是它当前所做的事情,也就是说,$-sigil变量上的trait尚未实现。很抱歉我在几英里外还是?如果我不在几英里之外,那么角色crud{}的工作又如何呢;类Foo{has@.baz是rw是crud};说Foo.new.baz~~crud;是的,即使用数组而不是标量?谢谢@raiph,这比我想做的要简单得多!谢谢困惑带来的解决方案:非常感谢伊丽莎白,这帮了大忙!我自己很难找到如何做到这一点,因为我上周在阅读了Naoum Hankache的Perl6简介之后才开始使用Perl6,这对于快速入门来说非常清晰有效。我正在等待一本Perl6概览书,并对发现更多内容感到非常兴奋。
Cannot modify an immutable Scalar+{crud} (Scalar+{crud}.new(crud => Bool::True))
  in block <unit> at t/08-attribute-trait.t line 30
multi trait_mod:<is>(Attribute $a, :$crud!) {
    # Something like this
    $a.container.VAR does set-crud;
}

class Foo {
    has $.bar is rw;
    has $.baz is rw is crud;
}