Question

converting list of Str into list of Enums

I have an enum definition in a module AAA:

enum RDProcDebug <None All AstBlock BlockType Scoping Templates MarkUp>;

class Debug {
  method foo(RDProcDebug @ds) {
    for @ds { say .key ~ ' => ' ~ .value }
  }
}

In Raku programs, this works well, eg

use AAA;
my RDProcDebug $rp .= new;
$r.foo(AstBlock, BlockType);

But now I need to supply the names of the debug elements from the command line, which can only supply Str, eg

$ RDOpts='AstBlock BlockType' raku myprog

# and in myprog
if %*ENV<RDOpts>:exists {
  $rp.debug( %*ENV<RDOpts> ); # this does not work
}

So how do I convert a list of Str into a list of type enum RDProcDebug ?

 3  28  3
1 Jan 1970

Solution

 2

Okay, so you want to pass those enum values from the command line, but there you only get strings. I get it. Here's what you can do:

First, grab that RDOpts from your environment and split it into separate words.

my @debug-options = %*ENV<RDOpts>.split(/\s+/);

Now here's the neat part. Raku has a trick to look up enum values by their name. It looks a bit weird, but it works like this:

my @debug-values = @debug-options.map({ RDProcDebug::{$_} });

What this does is check for each string in your list if there's a matching enum value. If all goes well, you'll end up with a list of actual RDProcDebug values. You can now just pass it to your debug method:

$rp.debug(@debug-values);

All together you would get something like this:

if %*ENV<RDOpts> {
my @debug-options = %*ENV<RDOpts>.split(/\s+/);
my @debug-values = @debug-options.map({ RDProcDebug::{$_} });
$rp.debug(@debug-values);}

Oh yeah, one more thing: if someone types in a wrong name, you'll get an error. You might want to do something about that..

2024-07-25
Salt