【问题标题】:How to use metaprogramming to create an enum in Perl 6?如何使用元编程在 Perl 6 中创建枚举?
【发布时间】:2018-04-12 12:11:19
【问题描述】:

给定表示枚举的数据,例如:

my %enums := {
  Color => { red => 0, black => 1, green => 2 },
  Status => { fail => 0, pass => 1 }
};

我如何使用Metamodel::ClassHOW 来创建等同于:

enum Color ( red => 0, black => 1, green => 2 );
enum Status ( fail => 0, pass => 1 );

Timo 的 ADT 库提供了一个如何使用 ClassHOW 创建类的示例,但它不包括枚举:https://github.com/timo/ADT/blob/master/lib/ADT.pm6

【问题讨论】:

  • Metamodel::Primitives 类似乎有可能,但我不知道如何。我将对此进行一些研究,看看我是否可以让它发挥作用。

标签: metaprogramming raku


【解决方案1】:

这似乎可以解决问题,但它大多未经测试:

my %enums := {
  Color => { red => 0, black => 1, green => 2 },
  Status => { fail => 0, pass => 1 }
};
my @types = gather {
    for %enums.kv -> $name, %values {
        my $type = Metamodel::EnumHOW.new_type(:$name, base_type => Int);
        for %values -> $pair {
            $type.^add_enum_value($pair);
        }
        $type.^add_role(Enumeration);
        $type.^add_role(NumericEnumeration);
        $type.^compose;
        take $type;
    }
}.list;
say @types;     # Output: [(Status) (Color)]

请注意,这会将类型放入数据结构中,因为词法范围在运行时是不可变的,因此您不能像使用 enum Color ... 那样声明它们。

【讨论】:

  • 谢谢,莫里茨。当我创建这样的类型时,我似乎无法访问它的任何数据。我希望 @types[0]::fail@types[0].enums 产生输出,但两者都没有。有什么想法吗?
  • @piojo 我忘了添加EnumerationNumericEnumeration 角色,请参阅我的更新答案。至于符号表访问,它不像变量那样工作。您必须通过@types[0].WHO 才能访问符号表。
  • 再次感谢。我似乎根本无法访问这些符号。我试过@types[0].WHO<fail>@types[0].WHO::fail@types[0]::fail@types[0]^::.keys@types[0].WHO.keys,但我在黑暗中拍摄。我得到的印象是我最好只使用哈希。如果我在容器$e 中定义了一个枚举类型,有没有办法获取一个键的值?
  • 要获取值,您可以再次使用 MOP:@types[0].^enum_values<pass> 将通过键为您提供值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-31
  • 1970-01-01
  • 1970-01-01
  • 2011-02-26
  • 2011-05-18
  • 2020-03-03
  • 1970-01-01
相关资源
最近更新 更多