Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 939
piojo Avatar asked Oct 31 '17 10:10

piojo


1 Answers

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 ....

like image 59
moritz Avatar answered Oct 17 '22 15:10

moritz