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 => { 'bar' => sub { $opts->{bar} = 1 }, 'baz=s' => sub { my %a = @_; $opts->{baz} = $a{value} }, 'err=s' => sub { die "Bzzt\n" }, }, argv => ["--baz", 1, "--bar"], # defaults to @ARGV ); if ($res->[0] == 200) { # do stuffs with parsed options, $opts } else { die $res->[1]; } Sample success result when @ARGV is ["--baz", 1, "--bar"]: [200, "OK", undef, { "func.remaining_argv" => [] }] Sample error result (ambiguous option) when @ARGV is ["--ba", 1]: [ 500, "Ambiguous option 'ba' (bar/baz?)", undef, { "func.ambiguous_opts" => { ba => ["bar", "baz"] }, "func.remaining_argv" => [1], }, ] Sample error result (option with missing value) when @ARGV is ["--bar", "--baz"]: [ 500, "Missing required value for option 'baz'", undef, { "func.remaining_argv" => [], "func.val_missing_opts" => { baz => 1 }, }, ] Sample error result (unknown option) when @ARGV is ["--foo", "--qux"]: [ 500, "Unknown options 'foo', 'qux'", undef, { "func.remaining_argv" => ["--foo", "--qux"], "func.unknown_opts" => { foo => 1, qux => 1 }, }, ] Sample error result (option with invalid value where the option handler dies) when @ARGV is ["--err", 1]: [ 500, "Invalid value for option 'err': Invalid value for option 'err': Bzzt\n", undef, { "func.remaining_argv" => [], "func.val_invalid_opts" => { err => "Invalid value for option 'err': Bzzt\n" }, }, ] 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