2
\$\begingroup\$

Inspired by this blogpost I decided to try and make it possible to have ranges of enum members that dwim, aka. that contain the actual members and not a stringified form.

This is the result. I'm looking for comments and wether I overlook a pitfall. Also, maybe EnumMember subset can be expressed in a more performant way?

use Test;

subset EnumMember of Any where .HOW.^name eq "Perl6::Metamodel::EnumHOW";

multi sub infix:<..>( EnumMember $a, EnumMember $b ) 
{
    die "Can only do ranges for members of the same enum" unless $a.WHAT === $b.WHAT;
    $a.WHAT.^enum_value_list.grep({ $_ === $a fff $_ === $b })
}

enum Foo ( XA => 17, XB => 19, XC => 2, XD => 17, XE => 1, XF => 99 );
enum Goo < YA YB >;

is-deeply( ( XC..XE ).Array, [XC, XD, XE] ); 
dies-ok({ XA..YB }); 
\$\endgroup\$
1
\$\begingroup\$

Probably, you could do something similar by ... and succ.

enum Foo ( XA => 17, XB => 19, XC => 2, XD => 17, XE => 1, XF => 99 );
enum Goo < YA YB >;
XC, *.succ ... XE andthen .say

Thus your example could be rewritten

use Test;

subset EnumMember of Enumeration; 

multi sub infix:<..>( EnumMember:D ::T $a, T:D $b ) {
    $a, *.succ ... $b 
}

multi sub infix:<..>( EnumMember $a,  $b ) {
    die 'Can only do ranges for members of the same enum' 
}

enum Foo ( XA => 17, XB => 19, XC => 2, XD => 17, XE => 1, XF => 99 );
enum Goo < YA YB >;

is-deeply( ( XC..XE ).Array, [XC, XD, XE] ); 
dies-ok({ XA..YB }); 

But you get Seq, not Range. So I prefer redefine the sequence operator ... and make a new role instead of a subtype.

use Test;

role EnumMember {}; 

multi sub infix:<...>( EnumMember:D ::T $a, T:D $b ) {
    $a, *.succ ... $b 
}

multi sub infix:<...>( EnumMember $a,  $b ) {
    fail 'Can only do sequence for members of the same enum' 
}

multi sub infix:<…>( EnumMember $a,  $b ) {
  $a ... $b
}

enum Foo does EnumMember ( XA => 17, XB => 19, XC => 2, XD => 17, XE => 1, XF => 99 );
enum Goo does EnumMember < YA YB >;

is (XC … XE), (XC, XD, XE); 
dies-ok { XA … YB }; 
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.