Adding two enums that share some same identifiers
The problem is that enum create symbols in their scope. Your code
enum Color <Red Blue>;
enum TrafficLight <Red Green>;
is basically doing
my \Color = Map.new(Red => 0, Blue => 1) does Enumeration;
my \Red := Color<Red>;
my \Blue := Color<Blue>;
my \Traffic-Light = Map.new(Red => 0, Green => 1) does Enumeration;
my \Red := Traffic-Light<Red>;
my \Green := Traffic-Light<Green>;
Thus you can see what generates the warning -- you can't create the symbol twice anymore than you can declare $x
twice in the same scope. Nonetheless, the two enum classes still exist, and can create values from the string "Red". One solution I've used in this case is to create a package and call the enum inside the package: Enum
package Color { enum Enum <Red Blue> }
package TrafficLight { enum Enum <Red Green> }
sub MAIN(
Color::Enum:D :c(:$color )!, #= the color
TrafficLight::Enum:D :t(:$traffic-light)!, #= the traffic-light
) {
say "Selected $color, Selected $traffic-light"
}
If you want to match against the values, then you just say Color::Red
or TrafficLight::Green
, or if you store things in a module so that you can use
, you could still use just Red
or Green
, just not in the same scope. So you could do:
sub MAIN(
Color::Enum:D :c(:$color )!, #= the color
TrafficLight::Enum:D :t(:$traffic-light)!, #= the traffic-light
) {
say "Selected $color, Selected $traffic-light"
{ # new scope
use MyEnums::Color;
given $color {
when Red { ... }
when Green { ... }
}
}
{ # separate new scope
use MyEnums::TrafficLight;
...
}
}