NAME
MooX::Role::CliOptions - Wrapper to simplify using Moo with Getopt::Long
VERSION
Version 0.04.1_004
SYNOPSIS
This is a minimal script that composes MooX::Role::CliOptions
.
#!/usr/bin/perl
package My::Moodulino;
use Moo;
with 'MooX::Role::CliOptions';
# initialize script attributes/variables
has option1 => (
is => 'ro',
isa => sub {
die 'Illegal value for option1'
unless $_[0] =~ /^foo|bar$/;
},
default => '',
);
...
# this makes the script a modulino
do {
my $app = __PACKAGE__->init(
argv => \@ARGV,
add_opts => [ 'option1=s' ],
);
exit $app->run;
} unless caller();
sub run {
my $self = shift;
...
return 0;
}
1; # must be present to satisfy "require" when testing
__END__
DESCRIPTION
This role was written to help standardize command line script behavior and, if written as a modulino, greatly improve testability. It should be noted that all example code snippets below are based on the modulino style but the normal, non-modulino style is also supported. See the example and test scripts in the distribution for further info if needed.
The default object created when composing this Role has the following structure (assuming a package name of My::Moodulino
as above and no additional attributes are defined in the composing class.)
$VAR1 = bless( {
'debug' => 1,
'verbose' => 1,
'argv' => []
}, 'My::Moodulino' );
EXPORTS
None. (Not applicable in a Role.)
ATTRIBUTES
Three read-only attributes are provided for the composing package, two of which are exposed as command line arguments and the third being created from the final @ARGV
values after processing by Getopt::Long
.
NOTE: Both debug
and verbose
can be eliminated from the Role by setting the environment variable MRC_NO_STDOPTS
to a "true" value before composing MooX::Role::CliOptions
into your script. This allows you to completely remove them or redefine them to suit your needs as desired. For example, you might want --debug
to be "off" by default. If you decide to redefine them you must supply a suitable attribute in your script. This does NOT affect the --help
or --man
command line options or the argv
attribute.
The following example demonstrates this:
#!perl!
# redefine --debug to be off by default and --verbose to indicate a level
# between 0 and 5
BEGIN {
$ENV{MRC_NO_STDOPTS} = 1;
}
use Moo;
with 'MooX::Role::CliOptions';
# not required but strongly recommended by ths author
use MooX::StrictConstructor;
has debug => (
is => 'ro',
default => 0,
);
has verbose => (
is => 'ro',
isa => sub {
die 'illegal value for --verbose'
unless $_[0] >= 0 && $_[0] <= 5;
},
default => 0,
);
do {
my $app = __PACKAGE__->init(
argv => \@ARGV,
add_opts => [
'debug',
'verbose=i',
],
);
exit $app->run;
} unless caller();
...
debug (Boolean read-only)
Exposed as the negatable --debug
command line option.
Default: Boolean TRUE (1). Is turned off with --nodebug
on the command line. (Paranoia is your friend.)
Commonly used to enable diagnostic reports and/or disable potentially dangerous operations such as database modifications.
Note: Implies the setting for verbose
if --verbose
or --noverbose
is not explicitly set on the command line.
verbose (Boolean read-only)
Exposed as the negatable --verbose
command line option.
Typically used to add extra information to the output. Often used in conjunction with --debug
.
Default: Will be the same as debug
if not explicitly set with either --verbose
or --noverbose
. This behavior was chosen since that is the most common usage pattern in the author's experience.
The most likely usage patterns would be
# in a crontab where no verbose output would be desired (verbose will
# default to OFF.)
/my_script --nodebug
# manually run from the cli where normal operation is needed and verbose
# output is desired
/my_script --nodebug --verbose
argv (read-only)
Returns an arrayref to the contents of @ARGV
after processing by Getopt::Long
. This is syntactic sugar for using @ARGV
directly.
Default: An empty arrayref if no command line arguments other than options recognized by Getopt::Long
are supplied.
OTHER COMMAND LINE OPTIONS
The following command line options are also accepted, but are not associated with an attribute since both will cause an immediate exit via Pod::Usage
after displaying the appropriate message.
--help
Will use pod2usage
to display the SYNOPSIS
or USAGE
POD section if available.
--man
Will use pod2usage
to display the full POD if available.
METHODS
init
This is the workhorse that integrates Getopt::Long
with the call to the composing package's new
constructor. Its return value is the resulting object of the composing package type.
Parameters
- argv (required)
-
Typically passed in as follows:
my $app = __PACKAGE__->init( argv => \@ARGV );
This will be passed to
Getopt::Long
for processing. Any remaining elements will be left in@ARGV
. They can also be accessed via$app->argv
. - add_opts (optional)
-
You can add your own command line options by using this. Simply place the
Getopt::Long
specification for any additional options that you want in an array ref as shown below and be sure to declare an attribute to hold the option data as processed byGetopt::Long
. (See the example scripts to make things clear.)# in your script has custom1 => ( is => 'ro', isa => sub { ... }, ); do { my $app = __PACKAGE__->init( argv => \@ARGV, add_opts => [ 'custom1=s', ], ); exit ($app->run || 0); } unless caller();
The above snippet would tell
Getopt::Long
to accept a command line option namedcustom1
that must be a string and place it in thecustom1
attribute that was declared. You may use any kind ofisa
orcoerce
test that you deem are needed as well as a default.
SEE ALSO
examples/moodulino.pl
for a functional modulino script.examples/myscript.pl
for a functional non-modulino script.
AUTHOR
Jim Bacon, <boftx at cpan.org>
BUGS
Please report any bugs or feature requests to bug-moox-role-clioptions at rt.cpan.org
, or through the web interface at https://rt.cpan.org/NoAuth/ReportBug.html?Queue=MooX-Role-CliOptions. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc MooX::Role::CliOptions
You can also look for information at:
RT: CPAN's request tracker (report bugs here)
https://rt.cpan.org/NoAuth/Bugs.html?Dist=MooX-Role-CliOptions
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
LICENSE AND COPYRIGHT
Copyright 2019 Jim Bacon.
This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at:
http://www.perlfoundation.org/artistic_license_2_0
Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.
If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.
This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.
This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.
Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.