=head1 NAME

OptArgs - integrated argument and option processing

=head1 VERSION

0.0.1 Development release.

=head1 SYNOPSIS

    #!/usr/bin/env perl
    use OptArgs;

    opt quiet => (
        isa     => 'Bool',
        alias   => 'q',
        comment => 'output nothing while working',
    );

    arg item => (
        isa      => 'Str',
        required => 1,
        comment  => 'the item to paint',
    );

    my $ref = optargs;

    print "Painting $ref->{item}\n" unless $ref->{quiet};

=head1 DESCRIPTION

B<OptArgs> processes command-line I<options> and I<arguments> for Perl
scripts. This is in contrast to anything anything in the Getopt::*
namespace that deals with command options only.

The following model is assumed by B<OptArgs> for command-line
applications:

=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. All
options have a long form prefixed by '--', and may have a single letter
alias prefixed by '-'.

=item Arguments

Arguments are positional parameters that that a command needs know in
order to do its work. Confusingly, arguments can be optional. The last
argument defined may be I<greedy>: it can consume everything else left
on the command line.

=item Sub-commands

From a users point of view sub-command arguments and options are
indistinguishable from arguments and options to the Command. Subcommand
options and arguments are defined in the same place as Command
arguments and options.  However from a code perspective they are
implemented as separate, stand-alone programs to be called by a dispatcher.

=back

=head2 Simple Scripts

To demonstrate lets put the code from the synopsis in a file called
C<paint> and observe the following interactions from the shell:

    $ ./paint
    usage: paint ITEM

      arguments:
        ITEM          the item to paint

      options:
        --quiet, -q   output nothing while working

As you can see a usage message is generated automatically. The
C<optargs()> function parses the command line according to the
declarations and returns a single HASH reference, easily interpolated
inside strings.

    $ ./paint house
    Painting house

Because B<OptArgs> knows about arguments it can detect more errors than
an option-only processing module:

    $ ./paint house car
    error: unexpected option or argument: car

The usage message is constructed based on option and argument
attributes. If we add another argument:

    arg colour => (
        isa     => 'Str',
        default => 'blue',
        comment => 'the colour to use',
    );

And then check the usage again:

    $ ./paint
    usage: paint ITEM [COLOUR]

      arguments:
        ITEM          the item to paint
        COLOUR        the colour to use

      options:
        --quiet, -q   output nothing while working

It can be seen that the non-required argument C<colour> appears inside
square brackets indicating its optional nature. Three dots (...) are
postfixed to greedy arguments. The order in which options and arguments
(and also sub-commands: see below) are defined is the order in which
they appear in usage messsages.

=head2 Sub-Command Scripts




=head1 FUNCTIONS

The following functions are exported (by default except for
C<dispatch>) using L<Exporter::Tidy>.

=over

=item opt( $name, %parameters )

Define a Command Option. If C<$name> contains underscores then aliases
with the underscores replaced by dashes (-) will be created. The
following parameters are accepted:

=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

A single character alias.

=item ishelp

When true flags this option as a help option, which when given on the
command line results in a usage message exception.  This flag is
basically a cleaner way of doing the following in each (sub) command:

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

=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

=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.

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

Returns a usage string prefixed with $message if given.

=item subcmd( @cmd, $description )

Create a sub-command. After this function is called further calls to
C<opt> and C<arg> define options and arguments respectively for the
sub-command.

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

Parse C<@ARGV> (or C<@argv> if given) and dispatch to the method
C<$method> in the appropriate package name constructed from C<$rootclass>.

=back

=head1 SEE ALSO

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

=head1 SUPPORT & DEVELOPMENT


This distribution is managed via github:

    https://github.com/mlawren/p5-OptArgs/tree/devel

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

=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.

