NAME
MooseX::Getopt::Defanged - Standard processing of command-line options, with Getopt::Long's nasty behavior defanged.
SYNOPSIS
package Some::Application
use Moose;
with qw< MooseX::Getopt::Defanged >;
# Sets up a standard command-line option that takes a value named
# 'some-option'.
has some_option => (
traits => [ qw< MooseX::Getopt::Defanged::Option > ],
is => 'rw',
isa => 'Str',
);
# Any Moose attributes that don't have the
# MooseX::Getopt::Defanged::Option trait are ignored.
has some_plain_attribute => (
is => 'rw',
isa => 'Str',
);
# Change the name of the command-line option with "getopt_name".
# So, instead of the user specifying "--different-named-option", they
# would specify "--blah".
has different_named_option => (
traits => [ qw< MooseX::Getopt::Defanged::Option > ],
is => 'rw',
isa => 'Str',
getopt_name => 'blah',
);
# Add alternate names for the option that the user can use via
# "getopt_aliases". In this case, the user will be able to specify
# "--option-with-aliases", "--aliases", or "-a".
has option_with_aliases => (
traits => [ qw< MooseX::Getopt::Defanged::Option > ],
is => 'rw',
isa => 'Str',
getopt_aliases => [ qw< aliases a > ],
);
# MooseX::Getopt::Defanged doesn't know how to handle your attribute type,
# but there's a means of automatically coercing from types that
# MooseX::Getopt::Defanged does know how to handle. Tell it what it
# should treat your attribute as by giving a value for "getopt_type".
subtype 'MyDateTime' => as 'DateTime';
coerce 'MyDateTime'
=> from 'Int'
=> via { DateTime->from_epoch(epoch => $_) };
coerce 'MyDateTime'
=> from 'Str'
=> via { DateTime::Format::Natural->new()->parse_datetime($_) };
has epoch_option => (
traits => [ qw< MooseX::Getopt::Defanged::Option > ],
is => 'rw',
isa => 'MyDateTime',
getopt_type => 'Int',
);
has natural_time_option => (
traits => [ qw< MooseX::Getopt::Defanged::Option > ],
is => 'rw',
isa => 'MyDateTime',
getopt_type => 'Str',
);
# Override the parsing part of the Getopt::Long specification with
# "getopt_specification", in this instance to allow the user to specify
# "--no-boolean-option".
has boolean_option => (
traits => [ qw< MooseX::Getopt::Defanged::Option > ],
is => 'rw',
isa => 'Bool',
getopt_specification => q<!>,
);
# Provide a default value for the option using the standard Moose means
# for defaults.
has int_option => (
traits => [ qw< MooseX::Getopt::Defanged::Option > ],
is => 'rw',
isa => 'Int',
default => 42,
);
# In addition to specifying the information on your option attributes, you
# need to actually invoke the command-line handling.
sub run_using_handle_for_output {
my ($self, $handle, $argv_ref) = @_;
$self->parse_command_line($argv_ref);
...
} # end run_using_handle_for_output()
VERSION
This document describes MooseX::Getopt::Defanged version 1.14.0.
DESCRIPTION
This is a Moose::Role for dealing with command-line options. The core implementation is ye olde Getopt::Long, so it helps to understand this if you read that documentation first. Among other things, this role defeats Getopt::Long's propensity for emitting stuff to STDERR
and for modifying @ARGV
.
Since this is a role for Moose, you use this by creating a class that uses this one via with
.
Due to Getopt::Long
limitations with multiple-valued options, bundling of single letter options is turned off. In other words, if there are options that can be specified as -x
and -y
, the user cannot use -xy
to specify them both.
INTERFACE
Since this is a role, this isn't something instantiable, so there are no constructors.
Attribute Options
Most of the time, you should be able to do nothing but use the traits
option, and everything should "just work". All of the other options are actually optional.
traits => [ qw< MooseX::Getopt::Defanged::Option ... > ]
-
The
traits
option is actually a standard one from Moose. It's how to tell this role that the attribute describes a command-line option.(If you need to trace the guts of the implementation of this role, note that there is no MooseX::Getopt::Defanged::Option class/role. Traits use the Moose plug-in mechanism, so start your investigation by looking at Moose::Meta::Attribute::Custom::Trait::MooseX::Getopt::Defanged::Option.)
getopt_name => 'name-on-the-command-line'
-
The
getopt_name
option allows you to change what the option will be referred to on the command-line. By default, the option name will be the same as the attribute name, with the underscores replaced by hyphens, e.g. an attribute with the name "foo_bar" will become a "--foo-bar" option.Note that an attribute with a name with a leading underscore (e.g. "_foo") will normally be rejected by this role because such attributes are considered to be private. In order to improve the usefulness of your program, you should allow your options to be driven by other Perl code. However, if you really want your attribute to be private, you can use this option to get around this restriction.
getopt_aliases => [ qw< alternate names > ]
-
If you want to allow the user to specify your option with other names than the primary one, this option takes a reference to an array of strings. This translates to the Getopt::Long "pipe|separated|alternatives" syntax.
getopt_type => 'AMooseType'
-
If what you specify for the standard
isa
option isn't what you want this role to treat as the type of your attribute, you can override it with this option. However, be careful of your attribute type constraints and make sure that there's a translation between theisa
andgetopt_type
types.Currently, this option is ignored if you specify a value for
getopt_specification
. getopt_specification => 'Getopt::Long format'
-
This allows you to completely override what this role will decide is the format to use for the attribute/option. This needs to be in the form of a Getopt::Long specification without the name and aliases part. For example, if you want to have an integer option with a required value that can be specified in "extended" format, you would give "=o" as the value for this option. Similarly, if you want an incrementing integer option, you can specify ":+".
You can find out the default types handled and their default specifications by looking at MooseX::Getopt::Defanged::OptionTypeMetadata.
Methods
parse_command_line($argv_ref)
-
Parses the command-line indicated by the parameter, which is expected to be a reference to an array of strings. Returns nothing.
Throws a MooseX::Getopt::Defanged::Exception::Generic if Getopt::Long complains about its parameters, e.g. if you give a bad option specification. Throws a MooseX::Getopt::Defanged::Exception::User if the user passes a bad option on the command-line.
get_remaining_argv()
-
After
parse_command_line()
is called, this method will get you what remains of@ARGV
as a list. get_option_type_metadata()
-
Returns the instance of MooseX::Getopt::Defanged::OptionTypeMetadata used to figure out defaults. You can use this to change how all options of a given type are handled.
ADDITIONAL EXAMPLES
For full details on how specifications work, refer to the Getopt::Long documentation. But here are some examples of what a resulting command line would look like, given a set of option attributes.
- Simple boolean.
-
An attribute like
has boolean_option => ( traits => [ qw< MooseX::Getopt::Defanged::Option > ], is => 'rw', isa => 'Bool', );
Will result in a command-line like
myprogram --boolean-option
where the user would specify the option if they wanted to turn it on and simply not specify the option if they wanted it off.
- Boolean that defaults to true, but can be turned off by the user.
-
has boolean_option => ( traits => [ qw< MooseX::Getopt::Defanged::Option > ], is => 'rw', isa => 'Bool', default => 1, getopt_specification => q<!>, );
The user could then say
myprogram --no-boolean-option
to turn it off or say
myprogram --boolean-option
to explicitly state the default (or be robust in the face of you changing the default).
- Integer with optional value.
-
The default specification for integers is
=i
, which means that the user must specify a value, i.e. if you have an attribute likehas int_option => ( traits => [ qw< MooseX::Getopt::Defanged::Option > ], is => 'rw', isa => 'Int', );
then the user has to use the option like this
myprogram --int-option 42
and
myprogram --int-option
will result in an error.
If you want the latter case to actually work, you can change the specification like so:
has int_option => ( traits => [ qw< MooseX::Getopt::Defanged::Option > ], is => 'rw', isa => 'Int', getopt_specification => ':i', );
In this scenario, if the user specifies the option without giving the value, the attribute will be set to
0
. If the user doesn't specify the option, the attribute will be undefined. - ArrayRef which requires precisely two values.
-
The default specification for ArrayRefs is
=«type»{1,}
, which means that the user must specify at least one value, but can specify more. E.g. the default specification for "ArrayRef[Num]" is=f{1,}
. Sohas some_numbers => ( traits => [ qw< MooseX::Getopt::Defanged::Option > ], is => 'rw', isa => 'ArrayRef[Num]', );
would mean that if the user specified
myprogram --some-numbers 2 1.3 0.61
then
some_numbers
would contain[2, 1.3, 0.61]
and specifying the option without any values would be an error.Now if you want the user to be required to specify two and only two options, you would change your attribute declaration to look like
has some_numbers => ( traits => [ qw< MooseX::Getopt::Defanged::Option > ], is => 'rw', isa => 'ArrayRef[Num]', getopt_specification => '=f{2}', );
- ArrayRef with each value specified separately.
-
As you can see from the above example, the defaults for ArrayRefs are set so that the user doesn't need to repeat the option for each value. If you prefer that each value be separately specified, change the attribute declaration to look like this:
has some_numbers => ( traits => [ qw< MooseX::Getopt::Defanged::Option > ], is => 'rw', isa => 'ArrayRef[Num]', getopt_specification => '=f@', );
The user would then need to use the option like
myprogram --some-numbers 2 --some-numbers 1.3 --some-numbers 0.61
DIAGNOSTICS
If you specify an attribute type that this class doesn't understand, a MooseX::Getopt::Defanged::Exception::InvalidSpecification will be thrown with the message There's no "$type_name" type.
.
If the user specifies an invalid option, an instance of MooseX::Getopt::Defanged::Exception::User will be thrown with the message from Getopt::Long, or Could not parse command-line.
if Getopt::Long doesn't provide one.
If an invalid Getopt::Long specification is found or it otherwise complains about something programmer specified, an instance of MooseX::Getopt::Defanged::Exception::Generic is thrown with Getopt::Long's message.
CONFIGURATION AND ENVIRONMENT
No external configuration is used. The "configuration" is done in your class on your attributes. See above.
DEPENDENCIES
perl 5.10
COMPARISONS
Differences with MooseX::Getopt:
- Causing parsing to happen.
-
MooseX::Getopt has you invoke a
new_with_options()
constructor. This module requires you to separately construct an object instance and invokeparse_command_line()
. - Picking which attributes result in command line options.
-
MooseX::Getopt makes all attributes command-line options by default and requires you to add a trait to the attributes that you don't want options for. This module does the opposite: you have to add a trait to attributes that you want command-line options for.
If you want the other MooseX::Getopt behavior but want to explicitly state which attributes turn into options, use MooseX::Getopt::Strict.
- Option parsing module used.
-
MooseX::Getopt will use Getopt::Long::Descriptive, if it is available. This module only uses Getopt::Long.
@ARGV
-
After parsing with MooseX::Getopt,
@ARGV
will have parsed options removed; a copy of it as it existed via prior to parsing is available via theARGV()
accessor. After parsing with this role,@ARGV
is unchanged. - Bad user input handling.
-
If the user specifies invalid options on the command-line, problems detected by MooseX::Getopt (actually Getopt::Long) will be emitted to
STDERR
. From this module, there is no output for bad user input; you will need to emit errors yourself. You can get at any error description via the message for the MooseX::Getopt::Defanged::Exception::User that will be thrown in this circumstance. - Configuration file merging.
-
This module has no support for merging configuration file contents with command-line options, but MooseX::Getopt does.
THE NAME
The author of this module does not like Getopt::Long's propensity for modifying @ARGV
and writing directly to STDERR
, so this role defangs it.
AUTHOR
Elliot Shank <perl@galumph.com>
LICENSE AND COPYRIGHT
Copyright ©2008-2009, Elliot Shank
DISCLAIMER OF WARRANTY
BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.