I use this idiom to parse command line arguments in Perl:
my @args;
my $encode = 1;
while (@ARGV) {
for (shift(@ARGV)) {
($_ eq '-h' || $_ eq '--help') && do { &usage(); };
# ... more options here
($_ eq '--') && do { push(@args, @ARGV); undef @ARGV; last; };
($_ =~ m/^-.+/) && do { print "Unknown option: $_\n"; &usage(); };
push(@args, $_);
}
}
This let's me do things like:
- Supports command line arguments in arbitrary order
- Supports using
--
to use any following arguments "as is", without parsing - Stop parsing and print usage message on
-h
, or--help
- Raise error if a
-something
flag is detected that is not matched by any of the parsing rules
Here's a short example script using this idiom:
#!/usr/bin/env perl
use strict;
use warnings;
&usage() unless @ARGV;
my @args;
my $encode = 1;
while (@ARGV) {
for (shift(@ARGV)) {
($_ eq '-h' || $_ eq '--help') && do { &usage(); };
($_ eq '-D' || $_ eq '--decode') && do { $encode = ! $encode; last; };
($_ eq '--') && do { push(@args, @ARGV); undef @ARGV; last; };
($_ =~ m/^-.+/) && do { print "Unknown option: $_\n"; &usage(); };
push(@args, $_);
}
}
sub usage {
$0 =~ m|[^/]+$|;
print "Usage: $& [-h|--help] [-D|--decode]\n";
print "\n";
print "Encode (= default) or decode Base64\n";
exit 1;
}
use MIME::Base64;
if ($encode) {
print map(&MIME::Base64::encode_base64($_), @args);
} else {
print map(&MIME::Base64::decode_base64($_), @args);
}
Is this a good technique for parsing command line arguments in Perl? Is there a better way?
I'm also interested in improvement ideas about the short script itself too.