Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document missing Enumeration and Metamodel::EnumHOW methods #2941

Merged
merged 2 commits into from Aug 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
65 changes: 53 additions & 12 deletions doc/Type/Enumeration.pod6
Expand Up @@ -122,6 +122,17 @@ Returns it as a C<Pair>.
=for code :preamble<<enum Mass<g> >>
say g.pair; # OUTPUT: «g => 1␤»

=head2 method CALL-ME

Defined as:

multi method CALL-ME(|)

Returns an C<Enumeration> instance given an enum value.

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

=head2 method pick

Defined as:
Expand All @@ -132,7 +143,7 @@ Defined as:

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

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

=head2 method roll
Expand All @@ -146,7 +157,7 @@ Defined as:
They work on the defined class selecting one or C<n> elements without
eliminating them.

=for code :preamble<enum Norse-gods <Þor Oðin Freija>;>
=for code :preamble«enum Norse-gods <Þor Oðin Freija>;»
say Norse-gods.roll() for ^3; # OUTPUT: «Freija␤Freija␤Oðin␤»

=head2 method pred
Expand All @@ -155,7 +166,7 @@ Defined as:

method pred(::?CLASS:D:)

=for code :preamble<enum Norse-gods <Þor Oðin Freija>;>
=for code :preamble«enum Norse-gods <Þor Oðin Freija>;»
say Freija.pred; # OUTPUT: «Oðin␤»

=head2 method succ
Expand All @@ -164,9 +175,25 @@ Defined as:

method succ(::?CLASS:D:)

=for code :preamble<enum Norse-gods <Þor Oðin Freija>;>
=for code :preamble«enum Norse-gods <Þor Oðin Freija>;»
say Oðin.succ; # OUTPUT: «Freija␤»

=head2 method Numeric

Defined as:

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

Takes a value of an enum and returns it after coercion to C<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 C<Numeric>, an exception
will be thrown.

=head2 method Int

Defined as:
Expand All @@ -175,16 +202,30 @@ Defined as:

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

enum Numbers <One Two Three>;
say Two.Int; # OUTPUT: «1␤»
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␤»

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

enum Numbers ( cool => '42', almost-pi => '3' );
say cool.Int; # OUTPUT: «42␤»
say almost-pi.Int; # OUTPUT: «3␤»
=head2 method Real

Note that if the value cannot be coerced to C<Int>, an exception will
Defined as:

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

Takes a value of an enum and returns it after coercion to C<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 C<Real>, an exception will
be thrown.

=head2 method C<===>
Expand All @@ -195,7 +236,7 @@ Defined as

Equality of C<Enumeration> symbols:

=for code :preamble< enum Norse-gods <Þor Oðin Freija>;>
=for code :preamble«enum Norse-gods <Þor Oðin Freija>;»
say Norse-gods.pick() === Freija for ^3; # OUTPUT: «False␤False␤True␤»


Expand Down
111 changes: 99 additions & 12 deletions doc/Type/Metamodel/EnumHOW.pod6
Expand Up @@ -22,56 +22,143 @@
does Metamodel::Mixins
{ }

C<Metamodel::EnumHOW> is the meta class behind the C<enum> keyword.
C<Metamodel::EnumHOW> is the meta-class behind the C<enum> keyword.

enum numbers <1 2>;
say numbers.HOW ~~ Metamodel::EnumHOW # OUTPUT: «True␤»
enum Numbers <1 2>;
say Numbers.HOW ~~ Metamodel::EnumHOW; # OUTPUT: «True␤»

The following enum declaration:

our Int enum Error <Warning Failure Exception Sorrow Panic>;

Is roughly equivalent to this code using C<Metamodel::EnumHOW>'s methods:

BEGIN {
my constant Error = Metamodel::EnumHOW.new_type: :name<Error>, :base_type(Int);
Error.^add_role: NumericEnumeration;
Error.^compose;
for <Warning Failure Exception Sorrow Panic>.kv -> Int $v, Str $k {
Error.^add_enum_value: $k => $v;
OUR::{$k} := Error.^enum_from_value: $v;
}
Error.^compose_values;
OUR::<Error> := Error;
}

I<Warning>: This class is part of the Rakudo implementation, and is not a part
of the language specification.

=head1 Methods

=head2 method new_type

method new_type(:$name!, :$base_type?, :$repr = 'P6opaque', :$is_mixin)

Creates a new type object for an enum. C<$name> is the enum name, C<$base_type>
is the type given when the enum is declared using a scoped declaration (if any),
and C<$repr> is the type representation passed to the enum using the C<repr>
trait. C<$is_mixin> is unused.

=head2 method add_parent

method add_parent($obj, $parent)

Sets the base type of an enum. This can only be used if no base type was passed
to C<.new_type>.

=head2 method set_export_callback

method set_export_callback($obj, $callback)

Sets the enum's export callback, which is invoked when calling
C<.compose_values>. This is called when applying the C<export> trait to an
enum. C<$callback> should be a routine of some sort, taking no arguments, that
handles exporting the enum's values.

=head2 method export_callback

method export_callback($obj)

Returns the export callback set by C<.set_export_callback>.

=head2 method compose

method compose($obj, :$compiler_services)

Completes a type object for an enum. This is when any roles done by the enum
are mixed in. This needs to be called before any enum values can be added using
C<.add_enum_value>.

=head2 method is_composed

method is_composed($obj)

Returns 1 if the enum is composed, otherwise returns 0.

=head2 method compose_values

method compose_values($obj)

Calls the export callback set by C<.set_export_callback> and removes it from
state. This should be called after adding the enum's values using
C<.add_enum_value>.

=head2 method set_composalizer

method set_composalizer($c)

Sets the composalizer for an enum, which produces a type that can be mixed in
with another. C<$c> should be a routine of some that has the following
signature:

:($type, $name, @enum_values)

=head2 method composalizer

method composalizer($obj)

Returns the composalizer set by C<.set_composalizer>.

=head2 method add_enum_value

method add_enum_value($obj, $value)

Adds a value to this enum.
Adds a value to this enum. C<$value> should be of type L<Pair|/type/Pair>.

=head2 method enum_values

method enum_values($obj)

Returns the values for the enum.

enum numbers <10 20>;
say numbers.^enum_values; # OUTPUT: {10 => 0, 20 => 1}
enum Numbers <10 20>;
say Numbers.^enum_values; # OUTPUT: {10 => 0, 20 => 1}

=head2 method elems

method elems($obj)

Returns the number of values.

enum numbers <10 20>;
say numbers.^elems; # OUTPUT: 2
enum Numbers <10 20>;
say Numbers.^elems; # OUTPUT: 2

=head2 method enum_from_value

method enum_from_value($obj, $value)

Given a value of the enum's base type, return the corresponding enum.

enum numbers <10 20>;
say numbers.^enum_from_value(0) # OUTPUT: 10
enum Numbers <10 20>;
say Numbers.^enum_from_value(0); # OUTPUT: 10

=head2 method enum_value_list

method enum_value_list($obj)

Returns a list of the enum values.

enum numbers <10 20>;
say numbers.^enum_value_list; # OUTPUT: (10 20)
enum Numbers <10 20>;
say Numbers.^enum_value_list; # OUTPUT: (10 20)

=end pod