=head1 NAME

OptArgs - integrated argument and option processing for Perl

=head1 VERSION

0.0.1 Development release.

=head1 SYNOPSIS

    use OptArgs;

    opt quiet => (
        isa     => 'Bool',
        alias   => 'q',
        comment => 'be quiet please',
    );

    arg item => (
        isa     => 'Str',
        default => 1,
        comment => 'try this many times',
    );

    my $ref = optargs;
    print "Working on: $ref->{item}\n" unless $ref->{quiet};

=head1 DESCRIPTION

B<OptArgs> provides command-line option and argument processing for
Perl scripts.  It is designed to be a very simple way to write programs
using a declarative style. L<Getopt::Long> is used for the underlying
parsing.

How exactly does one define a command line application? B<OptArgs>
assumes a fairly common (but by no means universal) approach:

=over

=item Command

The program name - i.e. the filename be executed by the shell.

=item Options

Options are parameters that affect the way a command runs. They are
generally not required to be present, but that is configurable. Options
are prefixed with '-' for single letter option names or '--' for long
option names.

=item Arguments

Arguments are positional parameters that that a command needs know in
order to do its work. Some arguments may be optional.

=item Sub-commands

A command may also have sub-commands with their own options and
arguments.  From the users point of view sub-commands and their options
are indisinguishable from options and arguments to the main command,
but from an implementation perspective they could (perhaps should) be
separate, stand-alone programs, with possibly their own set of
sub-commands.

=back

=head2 Declaring Options and Arguments

B<OptArgs> exports the following functions for defining Options and
Arguments. The order in which they are defined also determines the
order they appear in usage messages, and the order in which they are
processed.

=over

=item opt name => ( %parameters )

Define a Command Option with the following parameters:

=over

=item isa

Required. Is mapped to a L<Getopt::Long> type according to the
following table:

     optargs         Getopt::Long
    ------------------------------
     'Bool'          '!'
     'Counter'       '+'
     'Str'           '=s'
     'Int'           '=i'
     'Num'           '=f'
     'ArrayRef'      's@'
     'HashRef'       's%'

=item comment

Required. Used to generate the usage/help message.

=item default

The value set when the option is not used.

If this is a subroutine reference it will be called with a hashref
containg all option/argument values after parsing the source has
finished.  The value to be set must be returned, and any changes to the
hashref are ignored.

=item alias

Can be single characters or words separated by '|' if more than one
alias is desired. If the option name contains underscores ('_') then an
alias with '-' substitutions will be automatically added.

=item ishelp

When true flags this option as a help option, which when given on the
command line results in a usage message printed to I<stdout> followed
by an exit with a status of 2.  This flag is basically a shortcut to
save you from doing the following in each (sub) command:

    my $opts = optargs;
    if ( $opts->{help} ) {
        print usage('help requested');
        exit 2;
    }

=back

=item arg name => ( %parameters )

Define a Command Argument with the following parameters:

=over

=item isa

Required. Is mapped to a L<Getopt::Long> type according to the
following table:

     optargs         Getopt::Long
    ------------------------------
     'Str'           '=s'
     'Int'           '=i'
     'Num'           '=f'
     'ArrayRef'      's@'
     'HashRef'       's%'
     'SubCmd'        '=s'

=item comment

Required. Used to generate the usage/help message.

=item required

Set to a true value when the caller must specify this argument.  Can
not be used if a 'default' is given.

=item default

The value set when the argument is not given. Can not be used if
'required' is set.

If this is a subroutine reference it will be called with a hashref
containg all option/argument values after parsing the source has
finished.  The value to be set must be returned, and any changes to the
hashref are ignored.

=item greedy

If true the argument swallows the rest of the command line. It doesn't
make sense to define any more arguments once you have used this as they
will never be seen.

=item fallback

If C<isa> is a C<SubCmd> this option (when set) will stop the
generation of the usage message when the argument is not found as a
sub-command. The current command will be called instead. This option
when set must be a HASH reference containing "name" and "comment"
key/value pairs, which are only used in usage messages.

=back

=back

=head2 Parsing and Retrieving Values

B<OptArgs> exports the following functions for parsing and retriving
option and argument values:

=over

=item optargs( [ @argv ] ) -> HashRef

Parse @ARGV by default (or @argv when given) and returns a hashref
containing key/value pairs for options and arguments I<combined>.  An
error / usage exception is thrown if an invalid combination of options
and arguments is given.

Note that C<@ARGV> will be decoded into UTF-8 (if necessary) from
whatever L<I18N::Langinfo> says your environment encoding is.

=back

=head2 Utility Functions

=over

=item usage([$message]) -> Str

Returns a usage string based on the defined opts and args, prefixed
with $message if given.

=back

=head2 Writing Sub-Commands

B<OptArgs> exports the following functions for defining and running
subcommands.

=over

=item subcmd(@cmd, $description)

TBD.

=item dispatch($method, $rootclass, [ @argv ])

TBD.

=back

=head1 SEE ALSO

L<Getopt::Long>, L<Exporter::Tidy>

=head1 SUPPORT & DEVELOPMENT


This distribution is managed via github:

    http://github.com/mlawren/p5-OptArgs

This distribution follows the semantic versioning model:

    http://semver.org/

Code is tidied up on Git commit using githook-perltidy:

    http://github.com/mlawren/githook-perltidy

Test coverage according to L<Devel::Cover> is as follows:

    --------------------------------------------------------------
    File                  stmt  bran  cond   sub   pod  time total
    --------------------------------------------------------------
    blib/lib/optargs.pm   98.8  89.7 100.0 100.0 100.0  91.1  97.0
    lib/optargs.pod      100.0   n/a   n/a 100.0   n/a   8.9 100.0
    Total                 98.9  89.7 100.0 100.0 100.0 100.0  97.0
    --------------------------------------------------------------

=head1 AUTHOR

Mark Lawrence <nomad@null.net>

=head1 LICENSE

Copyright 2012 Mark Lawrence <nomad@null.net>

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.

