role Enumeration
ErrorsCollection

role Enumeration

Working with the role behind the enum type

role Enumeration { }

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 type types:

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

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 = %=> "T",
                      => "A",
                      => "G",
                      => "C" );
 
    method new$base-pair where "A" | "C" | "G" | "T" )  {
        self.blesskey => $base-pair,
                    value => %pairings{$base-pair});
    }
 
    multi method gist(::?CLASS:D:{
        return "$!key → $!value";
    }
 
}
 
enum Chain ();
constant length = 16;
for <A C G T>.rolllength ) -> $letter {
    my DNA $base = DNA.new$letter );
    Chain.HOW.add_enum_valueChain$base );
}
 
for ^length {
    my $base = Chain.pick;
    say "{$base.key} and {$base.value}";
}

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

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␤» 

Methods

These are the methods included in this role:

method key

An Enumeration property.

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

method value

These are Enumeration properties.

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

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 enums

method enums()

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

enum Mass ( mg => 1/1000=> 1/1kg => 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))␤»

method kv

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

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

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

method pair

method pair(::?CLASS:D:)

Returns it as a Pair.

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

method CALL-ME

multi method CALL-ME(|)

Returns an Enumeration instance given an enum value.

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

method pick

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

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

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

method roll

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

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␤» 

method pred

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

method succ

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

method Numeric

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

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␤»

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

method Int

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

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␤»

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

method Real

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

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␤»

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

method ===

multi infix:<===> (Enumeration:D \aEnumeration:D \b)

Equality of Enumeration symbols:

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