Ken, thanks for your writeup, including forcing me to learn a bit about Test -- I needed that! :-)
I'd rather stick with Perl's slice capability since it reads more cleanly (to me, anyway) and doesn't require copying and modifying the source array. Here's how I ended up implementing and testing pyrange():
#!/usr/bin/env perl
use v5.36;
use constant {
AREF => 0,
PYTHON => 1,
EXP => 2,
};
use Test::More;
my @test_array = 'a' .. 'g';
my @tests = (
[\@test_array, '[:3]', 'abc'],
[\@test_array, '[:-3]', 'abcd'],
[\@test_array, '[3:]', 'defg'],
[\@test_array, '[-3:]', 'efg'],
[\@test_array, '[-3:-1]', 'ef'], # testing double-ended ranges
[\@test_array, '[-3:-3]', ''],
[\@test_array, '[3:-1]', 'def'],
);
plan tests => 0+@tests;
for my $test (@tests) {
is get_array_slice_by_python_expr($test->@[AREF, PYTHON]),
$test->[EXP], "Testing: $test->[PYTHON]";
}
sub get_array_slice_by_python_expr ($aref, $python) {
### $re modified to return undef instead of '' when endpoint omitt
+ed
state $re = qr{^ \[ ( -? \d+ )? : ( -? \d+ )? \] $}x;
my ($start, $stop) = $python =~ $re;
my $range_aref = pyrange($aref, $start, $stop);
return join '', @$range_aref;
}
sub pyrange($aref, $start=undef, $stop=undef) {
if (!defined $start) {
$start = 0;
}
elsif ($start < 0) {
$start = @$aref + $start;
}
if (!defined $stop) {
$stop = $#$aref;
}
elsif ($stop >= 0) {
$stop = $stop - 1;
}
else {
$stop = @$aref + $stop - 1;
}
return [@$aref[$start .. $stop]];
}
Output:
$ ./test
1..7
ok 1 - Testing: [:3]
ok 2 - Testing: [:-3]
ok 3 - Testing: [3:]
ok 4 - Testing: [-3:]
ok 5 - Testing: [-3:-1]
ok 6 - Testing: [-3:-3]
ok 7 - Testing: [3:-1]
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.