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 }); 
rolfl
98.1k17 gold badges219 silver badges419 bronze badges
asked Oct 5, 2019 at 22:55
\$\endgroup\$

1 Answer 1

2
\$\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 }; 
answered Oct 6, 2019 at 8:02
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.