gpt4 book ai didi

traits - 性状中的混合角色显然不起作用

转载 作者:行者123 更新时间:2023-12-02 06:22:20 26 4
gpt4 key购买 nike

这个例子取了from roast ,尽管已经存在8年了:

role doc { has $.doc is rw }

multi trait_mod:<is>(Variable $a, :$docced!) {
$a does doc.new(doc => $docced);
}

my $dog is docced('barks');
say $dog.VAR;

这将返回 Any,而没有任何角色混合。尽管特质不会出错,但显然没有办法进入“doc”部分。任何想法?

最佳答案

(此答案基于@guifa的答案和JJ的评论。)

在可变特征中使用的惯用语本质上是$var.var.VAR

大声说起来听起来很有趣,但也似乎很疯狂。不是,但它至少需要解释,也许还需要某种形式的认知/句法缓解。

这是如何理解它的简短版本:

  • $var作为trait参数的名称是有意义的,因为它绑定(bind)到 Variable ,即编译器对变量的视点 View 。
  • 给定编译器的 View ,需要
  • .var来访问变量的用户 View 。
  • 如果变量是Scalar,则还需要.VAR来获取变量而不是它包含的值。 (如果它不是Scalar,则无害。)

  • 松一口气?

    我将在一个月中更详细地解释上述内容,但首先,如何缓解一下呢?

    也许我们可以引入一种执行 Variable的新 .var.VAR方法。但是,除非方法名称如此之好,否则从根本上消除了对该答案下一部分后面的 $var.var.VAR咒语解释的需要,否则这将是一个错误。

    但是我怀疑这样的名字是否存在。我想出的每个名字都会以某种方式使事情变得更糟。即使我们提出了一个完美的名字,充其量还是值得的。

    您原始示例的复杂性令我震惊。有一个 is特征,称为 does特征。因此,也许需要一个例程来抽象该复杂性和 $var.var.VAR。但是总有一些方法可以降低双重特征的复杂性,例如:
    role doc[$doc] { has $.doc is rw = $doc}
    my $dog does doc['barks'];
    say $dog.doc; # barks
    $var.var.VAR的详细说明

    But $v is already a variable. Why so many var and VARs?



    确实。 $v绑定(bind)到 Variable类的实例。这还不够吗?

    否,因为 Variable:
  • 用于在编译变量时存储有关变量的元数据。 (也许它应该被称为Metadata-About-A-Variable-Being-Compiled?只是在开玩笑。Variable在特征签名中看起来不错,并且更改其名称不会阻止我们继续使用和解释$var.var.VAR惯用语。)
  • 不是我们要寻找的机器人。我们需要用户对变量的看法。已经被声明和编译的代码,然后被用作用户代码的一部分。 (例如,$dog行中的say $dog...。即使它是BEGIN say $dog...,所以它在编译时运行,$dog仍将引用绑定(bind)到用户眼睛 View 容器或值的符号。它将不会引用Variable实例只是与变量相关的数据的编译器 View 。)
  • 使编译器和编写特质的人的生活更加轻松。但这要求特征编写者访问变量的用户视角,以访问或更改用户的视角。 .varVariable属性存储该用户的 View 。 (我注意到,烘烤测试具有省略的.container属性。现在已将其重命名为.var。我的猜测是,这是因为变量可能绑定(bind)到不可变值而不是容器,因此名称.container被认为具有误导性。)

  • 那么,我们如何到达 $var.var.VAR呢?

    让我们从原始代码的变体开始,然后继续。我将从 $dog切换到 @dog,然后从 .VAR行中删除 say:
    multi trait_mod:<is>(Variable $a, :$docced!) {
    $a does role { has $.doc = $docced }
    }

    my @dog is docced('barks');
    say @dog.doc; # No such method 'doc' for invocant of type 'Array'

    这几乎可行。一个微小的更改,它的工作原理是:
    multi trait_mod:<is>(Variable $a, :$docced!) {
    $a.var does role { has $.doc = $docced }
    }

    my @dog is docced('barks');
    say @dog.doc; # barks

    我所要做的就是在 .var行中添加 ... does role ...。在您的原始文章中,该行正在修改变量的编译器 View ,即绑定(bind)到 Variable$a对象。它不会修改变量的用户 View ,即绑定(bind)到 Array@dog

    据我所知,现在对于数组和哈希之类的复数容器,一切都可以正常工作:
    @dog[1] = 42;
    say @dog; # [(Any) 42]
    say @dog.doc; # barks

    但是,当我们尝试使用 Scalar变量时:
    my $dog is docced('barks');

    我们得到:
    Cannot use 'does' operator on a type object Any.

    这是因为 .var返回用户的眼睛 View 变量通常返回的内容。使用 Array可以得到 Array。但是通过 Scalar,您将获得 Scalar包含的值。 (这是P6的基本方面。它很好用,但是您必须在这种情况下知道它。)

    因此,要使它再次显示正常工作,我们还必须添加几个 .VAR。对于 Scalar以外的任何内容, .VAR是“无操作”,因此除了添加 Scalar之外,它对其他情况也没有危害:
    multi trait_mod:<is>(Variable $a, :$docced!) {
    $a.var.VAR does role { has $.doc = $docced }
    }

    现在, Scalar案例似乎也可以工作:
    my $dog is docced('barks');
    say $dog.VAR.doc; # barks

    (出于与我必须将其添加到 .VAR行相同的原因,我不得不在 say行中重新引入 $a.var.VAR ...。)

    如果一切都好,那将是答案的结尾。

    bug

    但是有些东西坏了。如果我们尝试初始化 Scalar变量:
    my $dog is docced('barks') = 42;

    我们会看到:
    Cannot assign to an immutable value

    正如@guifa和 I stumbled on a while back所指出的:

    It seems that a Scalar with a mixin no longer successfully functions as a container and the assignment fails. This currently looks to me like a bug.

    关于traits - 性状中的混合角色显然不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55933190/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com