# Ranges of enum members that dwim

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 });  ## 1 Answer 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 };