in reply to How do I process many (conflicting) command line parameters?
Many thanks for all the pointers. Some thoughts about the suggestions... and what I've been trying so far...
I have already generally been using Getopt::Std in my development, as I'm trying to keep things as simple as possible - 26 letters of the alphabet/switches (x2 for upper/lower case) is more than enough complexity for a poor user to deal with... but these options are practically reduced, as I prefer to try and use switches that are somehow helpful/intuitive -- "-t 10" for a time setting, "-v" for verbose logging, etc.
The article How do you use command line parameters? shows the standard way I've been doing things up-to-date, where each '$opt_x' item is tested and a flag set OR some action is performed. NOTE: I tend to use an 'if defined($opt_x) ...' construct to ONLY test if a command line switch has been specified; 'if ($opt_x)...' will not be satisfied if the command line switch has been specified AND it has a FALSE value -- which can lead to obscure bugs unless you're careful.
This sort of processing can be cumbersome, however, when there are many possible switches (look at something like Linux's rsync command). The C source of 'rsync' uses an 'enum' to define constants for its many options... and then uses a large 'case' statement that runs over many lines of code and gets difficult to follow very quickly...
...so I'm trying to see if there's any (standard) way to get around that sort of mess (other than making the Perl equivalent 'case' statement simply a despatcher of sorts ... which I note has now been mentioned and expanded upon... Fanx!).
The idea of using a bitfield is something more of a shortcut, I guess, to make it easier to weed-out the invalid combinations. For example, let's say we have the following:-
use Getopt::Std; getopts("lp"); # '-p' and '-l' will be recognized my $PORTRAIT = 1 << 3; # b3 = PORTRAIT orientation my $LANDSCAPE = 1 << 4; # b4 = LANDSCAPE my $LAYOUT_ERROR = $PORTRAIT | $LANDSCAPE; my $status = 0; if (defined ($opt_p)) { $status |= $PORTRAIT; } if (defined ($opt_l)) { $status |= $LANDSCAPE; } printf(" \$LANDSCAPE = %016b\n", $LANDSCAPE); printf(" \$PORTRAIT = %016b\n", $PORTRAIT); printf("\$LAYOUT_ERROR = %016b\n", $LAYOUT_ERROR); printf(" \$status = %016b\n", $status); if ( ($status & $LAYOUT_ERROR) == $LAYOUT_ERROR ) { die("ERR: Can't do both PORTRAIT and LANDSCAPE\n"); } printf("Continuing...\n");
This means that when a new switch is added, we simply add to the "bit shift" list... and add a bitwise 'OR' operation to the relevant 'mutually exclusive list'... and then do something with an 'if defined($opt_x) ...' item.
I guess I'm mainly trying to suss-out the 'best'(!?) way to code-up these sorts of operations in terms of someone having to maintain the code in a few years (even if that someone is likely to be me)...
|
|---|