Enums, Subsets and Coercions

25.1 Enums

enum Color <Red Green Blue>;               # Red = 0, Green = 1, Blue = 2
say Green, ' ', Green.value, ' ', +Blue;   # Green 1 2
say Color.enums;                           # Map.new((Blue => 2, Green => 1, Red => 0))
say Color(1);                              # Green
say Color::Red;

enum HTTPStatus (OK => 200, NotFound => 404, ServerError => 500);
say HTTPStatus(404);                       # NotFound
sub status-text(HTTPStatus $s) { $s.key }

enum Weekday (Mon => 1, <Tue Wed Thu Fri Sat Sun>);   # continues counting: Tue = 2...
say Sat.value;                             # 6
say Bool.enums;                            # Bool is an enum: False 0, True 1
given Blue {
    when Red  { say 'red' }
    when Blue { say 'blue' }
}

25.2 Subsets (Refinement Types)

subset Positive of Int where * > 0;
subset Percentage of Numeric where 0 <= * <= 100;
subset Email of Str where /^ <-[@\s]>+ '@' <-[@\s]>+ '.' \w+ $/;
subset NonEmpty of Str where *.chars > 0;
subset Small of Int where 1..10;

sub set-volume(Percentage $v) { say "Volume: $v%" }
set-volume(75);
# set-volume(150);                          # Constraint type check failed
my Email $e = '[email protected]';
say 5 ~~ Positive, ' ', -5 ~~ Positive;     # True False
multi classify(Positive $n) { 'positive' }
multi classify(Int $n)      { 'non-positive' }
say classify(3), ' ', classify(-3);

25.3 Coercion Types

class Celsius {
    has Numeric $.degrees;
    method COERCE(Numeric $d) { self.new(degrees => $d) }   # 6.d: enables Celsius(Numeric) coercion
}
sub show-temp(Celsius() $t) { say "{$t.degrees}°C" }
show-temp(25);                               # 25°C (coerced automatically)