NAME
Type::EnumHOW - Sugar for enum's meta-object protocol
SYNOPSIS
use Type::EnumHOW;
BEGIN {
my Str @ranks = 'Unranked', 'Voice', 'Half-Operator', 'Operator', 'Administrator', 'Owner';
my Str %symbols = %(
@ranks[0] => ' ',
@ranks[1] => '+',
@ranks[2] => '%',
@ranks[3] => '@',
@ranks[4] => '&',
@ranks[5] => '~'
);
my constant Rank = Type::EnumHOW.new_type: :name<Rank>, :base_type(Int);
Rank.^set_package: OUR;
Rank.^add_attribute_with_values: '$!symbol', %symbols, :type(Str);
Rank.^compose;
Rank.^add_enum_values: @ranks;
Rank.^compose_values;
};
say Owner; # OUTPUT: Owner
say Owner.symbol; # OUTPUT: ~
DESCRIPTION
Enums are not straightforward to create using their meta-object protocol since a large chunk of the work the runtime does to create enums is handled during precompilation. Type::EnumHOW extends Metamodel::EnumHOW to provide methods that both do the work normally done during precompilation and to provide sugar for customizing enum behaviour without the need to import nqp.
It is recommended to declare enums at compile-time rather than at runtime so enums and their values can have their serialization context set. This can be done by either using constant
in combination with do
or using BEGIN
.
Type::EnumHOW extends Metamodel::EnumHOW. Refer to its documentation for more information.
METHODS
Creates a new enum type. Named arguments are the same as those taken by Metamodel::EnumHOW.new_type
. If you plan on calling ^add_enum_values
with a list of keys, ensure you pass :base_type(Int)
.
Returns the package set by ^set_package
.
- ^set_package($package where *.WHO ~~ Stash | PseudoStash)
Sets the package in which the enum and its values' symbols will be installed. This must be called before calling ^compose
or ^add_enum_values
.
If MY
is given, the enum must be created during compilation. Any other package can be used during runtime.
Do not pass MY
packages in other lexpads to this method, such as OUTER::MY
or CALLER::MY
; enum and enum value symbols will get installed in the wrong lexpad. To the best of my knowledge, there isn't a good way to properly detect when they get passed when BEGIN
/constant
are involved.
- ^add_attribute_with_values(str $name, %values, Mu:U :$type = Any, Bool :$private = False)
Adds an attribute with the name $name
to the enum. %values
is a hash of enum value keys to attribute values that is used to bind the attribute values to their respective enum values when calling ^compose_values
. $type
is the type of the attribute values. If the attribute should be private, set $private
to True
, otherwise a getter will automatically be added.
Composes the enum type. Call this after adding enum attributes and methods, but before adding enum values.
If no package has been set using ^set_package
, an X::Type::EnumHOW::MissingPackage
exception will be thrown.
If the package was set to MY
and this wasn't called during compilation, an X::Type::EnumHOW::PostCompilationMY
exception will be thrown.
Batch adds a list of enum values to an enum and installs them both in the package set and the enum's package. ^compose
must be called before calling this. Calling this with a hash will warn about the enum values' order not necessarily being the same as when they were defined in the hash. This may also be called with either a list of keys or a list of pairs.
If no package has been set using ^set_package
, an X::Type::EnumHOW::MissingPackage
exception will be thrown.
If the package was set to MY
and this wasn't called during compilation, an X::Type::EnumHOW::PostCompilationMY
exception will be thrown.
AUTHOR
Ben Davies (Kaiepi)
COPYRIGHT AND LICENSE
Copyright 2019 Ben Davies
This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.