Parsing command line arguments in Perl 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') &amp;&amp; do { &amp;usage(); };
        # ... more options here
        ($_ eq '--') &amp;&amp; do { push(@args, @ARGV); undef @ARGV; last; };
        ($_ =~ m/^-.+/) &amp;&amp; do { print "Unknown option: $_\n"; &amp;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;

&amp;usage() unless @ARGV;

my @args;
my $encode = 1;

while (@ARGV) {
    for (shift(@ARGV)) {
        ($_ eq '-h' || $_ eq '--help') &amp;&amp; do { &amp;usage(); };
        ($_ eq '-D' || $_ eq '--decode') &amp;&amp; do { $encode = ! $encode; last; };
        ($_ eq '--') &amp;&amp; do { push(@args, @ARGV); undef @ARGV; last; };
        ($_ =~ m/^-.+/) &amp;&amp; do { print "Unknown option: $_\n"; &amp;usage(); };
        push(@args, $_);
    }
}

sub usage {
    $0 =~ m|[^/]+$|;
    print "Usage: $&amp; [-h|--help] [-D|--decode]\n";
    print "\n";
    print "Encode (= default) or decode Base64\n";
    exit 1;
}

use MIME::Base64;
if ($encode) {
    print map(&amp;MIME::Base64::encode_base64($_), @args);
} else {
    print map(&amp;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.
There are several modules on CPAN that are made for this task. They all reside in the Getopt namespace. Getopt::Long even comes with the standard distribution. So coming to your question: Yes, there are better ways. 

If you are interested in something more fancy, you could have a look at Getopt::Declare where you can write the usage page and fill your variables in the same place. It has a downside, though since it introduces another DSL.

What I definitely would recommend is that you take a look at &lt;&lt;HERE docs for printing longer texts. Some people dislike them,because of their strange syntactic properties, but they are the usual way to express multiline strings in perl.