piojo
piojo

Reputation: 6723

How to use metaprogramming to create an enum in Perl 6?

Given data that represents an enum, such as:

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

How can I use Metamodel::ClassHOW to create enums equivalent to:

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

Timo's ADT library gives an example of how to create a class with ClassHOW, but it doesn't cover enums: https://github.com/timo/ADT/blob/master/lib/ADT.pm6

Upvotes: 7

Views: 320

Answers (1)

moritz
moritz

Reputation: 12852

This seems to do the trick, but it's mostly untested:

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)]

Note that this puts the types into a data structure, because lexical scopes are immutable at run time, so you can't declare them just as you would with enum Color ....

Upvotes: 6

Related Questions