BrowserREPL-button-tip-on BrowserREPL-button-tip-off

EditButtonTip 2025-11-01

role Enumeration

Working with the role behind the enum type

role Enumeration { }
Code

This is the role implemented by the enum-pairs in the enum type. In general, it is used to create constant sets, the elements of which become also constant symbols in the current namespace and to establish a relationship between the symbols belonging to the same set. In general, you will find Enumeration in enum types:

enum norse-gods <Þor Oðin Loki>;
my $one-of-them = norse-gods.pick;
say $one-of-them.^name; # OUTPUT: «(norse-gods)␤»
say $one-of-them ~~ Enumeration; # OUTPUT: «True␤»
Code

but nothing prevents you from using it in your own programs if you want to restrict somehow the relationship between the key and the value:

class DNA does Enumeration {
    my %pairings = %( A => "T",
                      T => "A",
                      C => "G",
                      G => "C" );

    method new( $base-pair where "A" | "C" | "G" | "T" )  {
        self.bless( key => $base-pair,
                    value => %pairings{$base-pair});
    }

    multi method gist(::?CLASS:D:) {
        return "$!key → $!value";
    }

}

enum Chain ();
constant length = 16;
for <A C G T>.roll( length ) -> $letter {
    my DNA $base = DNA.new( $letter );
    Chain.HOW.add_enum_value( Chain, $base );
}

for ^length {
    my $base = Chain.pick;
    say "{$base.key} and {$base.value}";
}
Code

In this code, DNA consumes the Enumeration role, which is from this point of view a pair of key and value; we can use the generated DNA objects to compose an enum type from which elements can be picked one by one, with the output shown below.

T and A
C and G
T and A
# and so on...
Code

An item would smartmatch the enum class, but not the other way round:

enum Foo <bar baz>;
say baz ~~ Foo;  # OUTPUT: «True␤»
say Foo ~~ bar;  # OUTPUT: «False␤»
Code

Methods that work on the enum class§

As of release 2021.04 of the Rakudo compiler, an enum class can be considered as an instantiated Map object. This means you can use the keys, values, kv, pairs, antipairs, invert on an enum class and get the expected result.

enum Norse-gods <Þor Oðin Freija>;
say Norse-gods.keys; # OUTPUT: «(Þor Oðin Freija)␤»
Code

method enums§

method enums()
Code

Returns a Map of enum values. Works both on the enum type and any key.

enum Mass ( mg => 1/1000, g => 1/1, kg => 1000/1 );
say Mass.enums; # OUTPUT: «Map.new((g => 1, kg => 1000, mg => 0.001))␤»
say g.enums;    # OUTPUT: «Map.new((g => 1, kg => 1000, mg => 0.001))␤»
Code

Methods that work on the enum keys§

method key§

An Enumeration property.

enum Norse-gods <Þor Oðin Freija>;
say Freija.key; # OUTPUT: «Freija␤»
Code

method value§

These are Enumeration properties.

enum Norse-gods <Þor Oðin Freija>;
say Oðin.value; # OUTPUT: «1␤»
Code

The value is assigned automatically by the enum type starting at 0. Oðin gets 1 since it is the second in the enum.

method kv§

multi method kv(::?CLASS:D:)
Code

Returns a list with key and value of the enum-pair.

say g.kv; # OUTPUT: «(g 1)␤»
Code

method pair§

method pair(::?CLASS:D:)
Code

Returns it as a Pair.

say g.pair; # OUTPUT: «g => 1␤»
Code

method CALL-ME§

multi method CALL-ME(|)
Code

Returns an Enumeration instance given an enum value.

enum Mass ( mg => 1/1000, g => 1/1, kg => 1000/1 );
say Mass(1/1000); # OUTPUT: mg
Code

method pick§

multi method pick(::?CLASS:U:)
multi method pick(::?CLASS:U: \n)
multi method pick(::?CLASS:D: *@pos)
Code

It works on the defined class, selecting one element and eliminating it.

say Norse-gods.pick() for ^3;  # OUTPUT: «Þor␤Freija␤Oðin␤»
Code

method roll§

multi method roll(::?CLASS:U:)
multi method roll(::?CLASS:U: \n)
multi method roll(::?CLASS:D: *@pos)
Code

They work on the defined class selecting one or n elements without eliminating them.

say Norse-gods.roll() for ^3;  # OUTPUT: «Freija␤Freija␤Oðin␤»
Code

method pred§

method pred(::?CLASS:D:)
Code
say Freija.pred;  # OUTPUT: «Oðin␤»
Code

method succ§

method succ(::?CLASS:D:)
Code
say Oðin.succ;  # OUTPUT: «Freija␤»
Code

method Numeric§

multi method Numeric(::?CLASS:D:)
Code

Takes a value of an enum and returns it after coercion to Numeric:

enum Numbers ( cool => '42', almost-pi => '3.14', sqrt-n-one => 'i' );
say cool.Numeric;       # OUTPUT: «42␤»
say almost-pi.Numeric;  # OUTPUT: «3.14␤»
say sqrt-n-one.Numeric; # OUTPUT: «0+1i␤»
Code

Note that if the value cannot be coerced to Numeric, an exception will be thrown.

method Int§

multi method Int(::?CLASS:D:)
Code

Takes a value of an enum and returns it after coercion to Int:

enum Numbers ( cool => '42', almost-pi => '3.14', sqrt-n-one => 'i' );
say cool.Int;           # OUTPUT: «42␤»
say almost-pi.Int;      # OUTPUT: «3␤»
try say sqrt-n-one.Int;
say $!.message if $!;   # OUTPUT: «Cannot convert 0+1i to Int: imaginary part not zero␤»
Code

Note that if the value cannot be coerced to Int, an exception will be thrown.

method Real§

multi method Real(::?CLASS:D:)
Code

Takes a value of an enum and returns it after coercion to Real:

enum Numbers ( cool => '42', almost-pi => '3.14', sqrt-n-one => 'i' );
say cool.Real;           # OUTPUT: «42␤»
say almost-pi.Real;      # OUTPUT: «3.14␤»
try say sqrt-n-one.Real;
say $!.message if $!;    # OUTPUT: «Cannot convert 0+1i to Real: imaginary part not zero␤»
Code

Note that if the value cannot be coerced to Real, an exception will be thrown.

method ===§

multi infix:<===> (Enumeration:D \a, Enumeration:D \b)
Code

Equality of Enumeration symbols:

say Norse-gods.pick() === Freija for ^3; # OUTPUT: «False␤False␤True␤»
Code