SYNOPSIS use Getopt::Panjang qw(get_options); my $opts; my $res = get_options( # similar to Getopt::Long, except values must be coderef (handler), and # handler receives hash argument spec => { 'foo' => sub { $opts->{foo} = 1 }, 'bar=s' => sub { my %a = @_; $opts->{bar} = $a{value} }, }, argv => ["--bar", 1, "--foo"], # defaults to @ARGV ); if ($res->[0] == 200) { # do stuffs with parsed options, $opts } else { warn "Can't parse command-line options"; if ($res->[3]{'func.unknown_opts'}) { warn "There are some unknown options: ", join(",", keys %{$res->[3]{'func.unknown_opts'}}); } if ($res->[3]{'func.ambiguous_opts'}) { warn "There are some ambiguous options: ", join(",", keys %{$res->[3]{'func.ambiguous_opts'}}); } if ($res->[3]{'func.val_missing_opts'}) { warn "There are some options which miss values: ", join(",", keys %{$res->[3]{'func.val_missing_opts'}}); } if ($res->[3]{'func.val_invalid_opts'}) { warn "There are some options with invalid values: ", join(",", keys %{$res->[3]{'func.val_invalid_opts'}}); } } DESCRIPTION EXPERIMENTAL WORK. This module is similar to Getopt::Long, but with a rather different interface. After experimenting with Getopt::Long::Less and Getopt::Long::EvenLess (which offers interface compatibility with Getopt::Long), I'm now trying a different interface which will enable me to "clean up" or do "more advanced" stuffs. Here are the goals of Getopt::Panjang: * low startup overhead Less than Getopt::Long, comparable to Getopt::Long::EvenLess. * feature parity with Getopt::Long::EvenLess More features will be offered in the future. * more detailed error return This is the main goal which motivates me to write Getopt::Panjang. In Getopt::Long, if there is an error like an unknown option, or validation error for an option's value, or missing option value, you only get a string warning. Getopt::Panjang will instead return a data structure with more details so you can know which option is missing the value, which unknown option is specified by the user, etc. This will enable scripts/frameworks to do something about it, e.g. suggest the correct option when mistyped. The interface differences with Getopt::Long: * There is only a single function, and no default exports Getopt::Long has GetOptions, GetOptionsFromArray, GetOptionsFromString. We only offer get_options which must be exported explicitly. * capitalization of function names Lowercase with underscores (get_options) is used instead of camel case (GetOptions). * get_options accepts hash argument This future-proofs the function when we want to add more configuration. * option handler also accepts hash argument This future-proofs the handler when we want to give more arguments to the handler. * There are no globals Every configuration is specified through the get_options function. This is cleaner. * get_options never dies, never prints warnings It only returns the detailed error structure so you can do whatever about it. * get_options never modifies argv/@ARGV Remaining argv after parsing is returned in the result metadata. Sample startup overhead benchmark: # COMMAND: perl devscripts/bench-startup 2>&1 SEE ALSO Getopt::Long Getopt::Long::Less, Getopt::Long::EvenLess Perinci::Sub::Getopt