I have a table of commands to run and want to provide a convenient command line user interface to allow the user to select which (zero-based) indices from the table (implemented as a Perl array) to run.

Assuming a command table of eleven commands, say (index 0..10) you might try:

somecommand 4 # run index 4 from the command table somecommand 4-6 # run indices 4,5,6 from the command table somecommand 5- # run indices 5,6,7,8,9,10 from the command table somecommand -2 # run indices 0,1,2 from the command table
This covers the common case of running a range of contiguous commands. Suggestions for a nice command line user interface welcome.

Given the user interface described above, I wrote a function to convert from the user interface "range string" to a list suitable for use in a Perl array slice.

use strict; use warnings; # This function takes a "range string" and returns # a list that can be used in a Perl array slice. # Some examples should clarify: # Range string Return list # "4" (4) # "4-6" (4,5,6) # "5-" (5,6,7,...,$maxind) # "-2" (0,1,2) sub range_to_list { my $maxind = shift; # max index of (zero-based) list my $range = shift; # a "range string" (see examples above) my @ilist = split /-/, $range, 2; my $nlist = @ilist; $nlist == 1 || $nlist == 2 or die "range_to_list $nlist out of rang +e"; if ( $nlist == 1 ) { $ilist[0] =~ /^\d+$/ or die "range_to_list, '$ilist[0]' not nume +ric"; $ilist[0] <= $maxind or die "range_to_list, '$ilist[0]' out of r +ange"; return @ilist; } if ( $ilist[0] eq '' ) # e.g. "-5" case { $ilist[1] =~ /^\d+$/ or die "range_to_list, '$ilist[1]' not nume +ric"; $ilist[1] <= $maxind or die "range_to_list, '$ilist[1]' out of r +ange"; return ( 0 .. $ilist[1] ); } if ( $ilist[1] eq '' ) # e.g. "3-" case { $ilist[0] =~ /^\d+$/ or die "range_to_list, '$ilist[0]' not nume +ric"; $ilist[0] <= $maxind or die "range_to_list, '$ilist[0]' out of r +ange"; return ( $ilist[0] .. $maxind ); } # e.g. "3-5" case $ilist[0] =~ /^\d+$/ or die "range_to_list, '$ilist[0]' not numeric +"; $ilist[1] =~ /^\d+$/ or die "range_to_list, '$ilist[1]' not numeric +"; return ( $ilist[0] .. $ilist[1] ); } my $maxind = 10; print "maxind=$maxind\n"; for my $rstr ( "x", "1-2-3", "0", "10", "11", "4", "4-6", "7-", "-2", "-10", "-11", "-0", "10-", "11-" ) { print "rstr:$rstr:"; my @ret; eval { @ret = range_to_list( $maxind, $rstr ) }; if ($@) { print "...exc:$@"; } else { print "...ret:@ret:\n"; } } my @apples = ( ":zero:", ":one:", ":two:", ":three:", ":four:" ); print "apples ", @apples[range_to_list( $#apples, "1-3" )], "\n";
To clarify the spec, note that running the test program rl.pl above produces:
maxind=10 rstr:x:...exc:range_to_list, 'x' not numeric at rl.pl line 21. rstr:1-2-3:...exc:range_to_list, '2-3' not numeric at rl.pl line 39. rstr:0:...ret:0: rstr:10:...ret:10: rstr:11:...exc:range_to_list, '11' out of range at rl.pl line 22. rstr:4:...ret:4: rstr:4-6:...ret:4 5 6: rstr:7-:...ret:7 8 9 10: rstr:-2:...ret:0 1 2: rstr:-10:...ret:0 1 2 3 4 5 6 7 8 9 10: rstr:-11:...exc:range_to_list, '11' out of range at rl.pl line 28. rstr:-0:...ret:0: rstr:10-:...ret:10: rstr:11-:...exc:range_to_list, '11' out of range at rl.pl line 34. apples :one::two::three:
Implementation improvements of this inelegant first attempt welcome.


In reply to Specifying a range of indices via the command line by eyepopslikeamosquito

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.