Okay, took the hint and did it all with slices. Does this look right?
use v5.36;
no warnings q/experimental/; # no warns about for-list
sub range($aref, $start=undef, $end=undef) {
if (!defined $start) {
$start = 0;
if ($end >= 0) {
$end = $end - 1;
}
else {
$end = $#$aref + $end;
}
}
elsif (!defined $end) {
$end = $#$aref;
if ($start < 0) {
$start = $#$aref + $start + 1 ;
}
}
else {
die "a[i:j] ranges not supported yet";
}
print "\@a[$start .. $end] ";
return [@$aref[$start .. $end]];
}
my @a = qw/a b c d e f g/;
my @tests = (
[3, undef, 'defg'],
[0, undef, 'abcdefg'],
[-3, undef, 'efg'],
[undef, 3, 'abc'],
[undef, 0, ''],
[undef, -3, 'abcd'],
);
for my ($i, $j, $answer) (map {@{$_}} @tests) {
printf("a[%s:%s] -> ", $i // '', $j // '');
printf("range(a, %s, %s) -> ", $i // 'undef', $j // 'undef');
my $aref = range(\@a, $i, $j);
my $join = join '', @$aref;
printf("'$join', expecting '$answer'\n");
}
And it checks out:
a[3:] -> range(a, 3, undef) -> @a[3 .. 6] 'defg', expecting 'defg'
a[0:] -> range(a, 0, undef) -> @a[0 .. 6] 'abcdefg', expecting 'abcdef
+g'
a[-3:] -> range(a, -3, undef) -> @a[4 .. 6] 'efg', expecting 'efg'
a[:3] -> range(a, undef, 3) -> @a[0 .. 2] 'abc', expecting 'abc'
a[:0] -> range(a, undef, 0) -> @a[0 .. -1] '', expecting ''
a[:-3] -> range(a, undef, -3) -> @a[0 .. 3] 'abcd', expecting 'abcd'
|