如何在 Perl 6 中为我的自定义 Class 添加下标?

How to add subscripts to my custom Class in Perl 6?

我是 Perl 6 的新手。我的 Atom 编辑器中有以下代码,但我仍然不明白它是如何工作的。正如docs.raku.org所说,我复制了下面的代码,但似乎不起作用。所以我将代码更改为:

use v6;

class HTTPHeader { ... }

class HTTPHeader does Associative  {

    has %!fields  handles <self.AT-KEY self.EXISTS-KEY self.DELETE-KEY self.push
                          list kv keys values>;
    method Str { say self.hash.fmt; }


    multi method EXISTS-KEY ($key)       { %!fields{normalize-key $key}:exists }
    multi method DELETE-KEY ($key)       { %!fields{normalize-key $key}:delete }
    multi method push (*@_)              { %!fields.push: @_                   }

    sub normalize-key ($key) { $key.subst(/\w+/, *.tc, :g) } 

    method AT-KEY (::?CLASS:D: $key) is rw {
        my $element := %!fields{normalize-key $key};

        Proxy.new(
            FETCH => method () { $element },

            STORE => method ($value) {
                $element = do given $value».split(/',' \s+/).flat {
                    when 1  { .[0] }    # a single value is stored as a string
                    default { .Array }  # multiple values are stored as an array
                }
            }
        );
    }
}


my $header = HTTPHeader.new;
say $header.WHAT;  #-> (HTTPHeader)
"".say;

$header<Accept> = "text/plain";
$header{'Accept-' X~ <Charset Encoding Language>} = <utf-8 gzip en>;
$header.push('Accept-Language' => "fr");  # like .push on a Hash

say $header.hash.fmt;
"".say;


say $header<Accept-Language>.values; 
say $header<Accept-Charset>;

输出是:

(HTTPHeader)

Accept  text/plain
Accept-Charset  utf-8
Accept-Encoding gzip
Accept-Language en fr

(en fr)
utf-8

我知道它可以工作,但是docs.raku.org中的文档与这个有点不同,它在第7行的AT-KEY方法之前没有"self"。有没有更详细的例子?

Is there any examples that more detail about this?

Stack overflow 并不是真正请求有关已发布示例的更多详细信息的地方。 This 是社区本身的 perl6 doco - 如果您有进一步的疑问,我建议最合适的地方是 Perl6 用户邮件列表,或者,如果不行的话,IRC 频道。

虽然你已经发布了它,但我还是犹豫要不要让这个问题得到解决,所以,这里有一些事情需要考虑;

首先 - 您提出的示例是关于在自定义(即用户定义)上实现关联下标 class - 这不是 self-described 新手的典型领域。我认为你最好看看 Perl6 introNaoum Hankache 的示例并加以实施,他的网站受到了很好的欢迎。

选项 1 - 通过授权轻松实施

其次,了解该示例显示 三个 实现关联下标的选项很重要;第一个也是最简单的使用委托给私有散列属性。 Perl6 通过在实现 collection 类型的 object 上调用 well-defined 方法来实现关联和位置下标(对于 built-in 类型)。通过在 %!fields 属性定义的末尾添加 handles 特征,您只需将这些方法调用传递给 %!fields ,它 - 作为哈希 - 将知道如何处理他们。

选项 2 - 灵活键

引用例子: 但是,HTTP header 字段名称应该是 case-insensitive(在 camel-case 中是首选)。我们可以通过将 *-KEYpush 方法从句柄列表中取出,并分别实现它们来解决这个问题...

将所有 key-handling 方法委托给内部散列意味着您可以 hash-like 解释您的键 - 这意味着它们将是 case-sensitive,因为散列键是 case-sensitive。为避免这种情况,您将所有 key-related 方法 从 handles 子句 中取出并自己实现它们。在示例中,键是 运行 到 "normalizer",然后用作 %!fields 的索引,使它们成为 case-insensitive.

选项 3 - 灵活值

示例的最后一部分展示了如何控制 进入 hash-like 容器时的解释。到目前为止,通过分配给此自定义容器的实例提供的值必须是字符串或字符串数​​组。额外的控制是通过 删除选项 2 中定义的 AT_KEY 方法 并将其替换为提供 Proxy Object 的方法来实现的。如果您正在分配给容器并且 that 方法扫描提供的字符串值 ,代理 object 的 STORE 方法将被调用” , "(注意:space 是复合的),如果找到,将接受字符串值作为多个字符串值的规范。至少,我是这么认为的。

因此,该示例包含的内容比看起来要多得多。你 运行 遇到了麻烦 - 正如 Brad 在评论中指出的那样 - 因为你在复制示例时 sort-of 将选项 1 与选项 3 混在一起。