【发布时间】:2020-09-17 16:18:18
【问题描述】:
在 Raku 中,HOW 必须通过 archetypes 方法公开一个原型列表,该方法用于确定类型实现的类型的更广泛的特性,例如参数性或可组合性。我注意到Metamodel::EnumHOW(与枚举一起使用的方式)具有augmentable 原型,当启用MONKEY-TYPING pragma 时,它被赋予在使用augment 关键字组合后可以扩展的类型。
我对枚举为什么可以增加的第一个猜测是允许添加枚举值,所以我试着写这个:
use v6;
use MONKEY-TYPING;
enum Foo <foo bar baz>;
augment enum Foo <qux>;
say qux;
但这会引发:
bastille% raku test.raku
===SORRY!=== Error while compiling /home/morfent/test.raku
Redeclaration of symbol 'Foo'.
at /home/morfent/test.raku:5
------> augment enum Foo⏏ <qux>;
所以他们可能不打算以这种方式增强。
我的下一个猜测是,它们旨在针对枚举值而不是枚举类型本身进行扩充。 augment,有趣的是,当你告诉它你正在扩充哪种类型时,它没有考虑到一个类型实际上有什么,所以我尝试像你对一个类一样扩充一个枚举:
use v6;
use MONKEY-TYPING;
enum Foo <foo bar baz>;
augment class Foo {
proto method is-foo(::?CLASS:D: --> Bool:D) {*}
multi method is-foo(foo: --> True) { }
multi method is-foo(::?CLASS:D: --> False) { }
}
say foo.is-foo;
哪个有效:
bastille% raku test.raku
True
但这并不像是你打算如何为我增加枚举。 augment 的这种用法相当奇怪,并且从其文档中没有任何暗示应该可以做到这一点。您打算如何扩充枚举?
常见问题解答
-
Foo.is-foo似乎没有任何代码?它在做什么?
is-foo 在使用签名和参数的特性方面相当严厉。这取决于以下几点:
- 常量值可以像签名中的类型一样使用。这包括在编译时处理的枚举值。
- 可以使例程始终返回一个常量值,方法是为其签名的返回值类型设置一个。
- 签名中任何给定参数的变量都是可选的。
- 当像这样在第一个参数之后放置一个冒号时,第一个参数就是签名的invocant。对于方法,这允许您随意输入
self。 -
::?CLASS是在其范围内声明方法的类的别名。它存在于类和角色主体中,因此尽管Foo不是真正的类,但这就是该符号所指的。 -
:D是一个类型笑脸,表示一个类型应该只对它自己的实例进行类型检查,而不是类型检查类似它的类型对象。
由于foo 是比::?CLASS:D(Foo:D 的别名)更具体的类型,因此在foo 上调用此方法时,将选择foo multi 并返回True,但在任何其他情况下,::?CLASS:D multi 将被选中,False 将被返回。
【问题讨论】:
标签: enums metaprogramming raku