# NAME
MooX::Options - Explicit Options eXtension for Object Class
# SYNOPSIS
In myOptions.pm :
package myOptions;
use Moo;
use MooX::Options;
option 'show_this_file' => (
is => 'ro',
format => 's',
required => 1,
doc => 'the file to display'
);
1;
In myTool.pl :
use myOptions;
use Path::Class;
my $opt = myOptions->new_with_options;
print "Content of the file : ",
file($opt->show_this_file)->slurp;
To use it :
perl myTool.pl --show_this_file=myFile.txt
Content of the file: myFile content
The help message :
perl myTool.pl --help
USAGE: myTool.pl [-h] [long options...]
--show_this_file: String
the file to display
-h --help:
show this help message
--man:
show the manual
The usage message :
perl myTool.pl --usage
USAGE: myTool.pl [ --show_this_file=String ] [ --usage ] [ --help ] [ --man ]
The manual :
perl myTool.pl --man
# DESCRIPTION
Create a command line tool with your [Mo](https://metacpan.org/pod/Mo), [Moo](https://metacpan.org/pod/Moo), [Moose](https://metacpan.org/pod/Moose) objects.
Everything is explicit. You have an `option` keyword to replace the usual `has` to explicitly use your attribute into the command line.
The `option` keyword takes additional parameters and uses [Getopt::Long::Descriptive](https://metacpan.org/pod/Getopt::Long::Descriptive)
to generate a command line tool.
# IMPORTANT CHANGES IN 4.100
## Enhancing existing attributes
One can now convert an existing attribute into an option for obvious reasons.
package CommonRole;
use Moo::Role;
has attr => (is => "ro", ...);
sub common_logic { ... }
1;
package Suitable::Cmd::CLI;
use Moo;
use MooX::Cmd;
use MooX::Options;
with "CommonRole";
option '+attr' => (format => 's', repeatable => 1);
sub execute { shift->common_logic }
1;
package Suitable::Web::Request::Handler;
use Moo;
with "CommonRole";
sub all_suits { shift->common_logic }
1;
package Suitable::Web;
use Dancer2;
use Suitable::Web::Request::Handler;
set serializer => "JSON";
get '/suits' => sub {
$my $reqh = Suitable::Web::Request::Handler->new( attr => config->{suit_attr} );
$reqh->all_suits;
};
dance;
1;
Of course there more ways to to it, [Jedi](https://metacpan.org/pod/Jedi) or [Catalyst](https://metacpan.org/pod/Catalyst) shall be fine, either.
## Rename negativable into negatable
Since users stated that `negativable` is not a reasonable word, the flag is
renamed into negatable. Those who will 2020 continue use negativable might
or might not be warned about soon depreciation.
## Replace Locale::TextDomain by MooX::Locale::Passthrough
[Locale::TextDomain](https://metacpan.org/pod/Locale::TextDomain) is broken (technically and functionally) and causes a
lot of people to avoid `MooX::Options` or hack around. Both is unintened.
So introduce [MooX::Locale::Passthrough](https://metacpan.org/pod/MooX::Locale::Passthrough) to allow any vendor to add reasonable
localization, eg. by composing [MooX::Locale::TextDomain::OO](https://metacpan.org/pod/MooX::Locale::TextDomain::OO) into it's
solution and initialize the localization in a reasonable way.
## Make lazy loaded features optional
Since some features aren't used on a regular basis, their dependencies have
been downgraded to `recommended` or `suggested`. The optional features are:
- autosplit
This feature allowes one to split option arguments at a defined character and
always return an array (implicit flag `repeatable`).
option "search_path" => ( is => "ro", required => 1, autosplit => ":", format => "s" );
However, this feature requires following modules are provided:
- [Data::Record](https://metacpan.org/pod/Data::Record)
- [Regexp::Common](https://metacpan.org/pod/Regexp::Common)
- json format
This feature allowes one to invoke a script like
$ my-tool --json-attr '{ "gem": "sapphire", "color": "blue" }'
It might be a reasonable enhancement to _handles_.
Handling JSON formatted arguments requires any of those modules
are loded:
- [JSON::MaybeXS](https://metacpan.org/pod/JSON::MaybeXS)
- [JSON::PP](https://metacpan.org/pod/JSON::PP) (in Core since 5.14).
## Decouple autorange and autosplit
Until 4.023, any option which had autorange enabled got autosplit enabled, too.
Since autosplit might not work correctly and for a reasonable amount of users
the fact of
$ my-tool --range 1..5
is all they desire, autosplit will enabled only when the dependencies of
autosplit are fulfilled.
# IMPORTED METHODS
The list of the methods automatically imported into your class.
## new\_with\_options
It will parse your command line params and your inline params, validate and call the `new` method.
myTool --str=ko
t->new_with_options()->str # ko
t->new_with_options(str => 'ok')->str #ok
## option
The `option` keyword replaces the `has` method and adds support for special options for the command line only.
See ["OPTION PARAMETERS"](#option-parameters) for the documentation.
## options\_usage | --help
It displays the usage message and returns the exit code.
my $t = t->new_with_options();
my $exit_code = 1;
my $pre_message = "str is not valid";
$t->options_usage($exit_code, $pre_message);
This method is also automatically fired if the command option "--help" is passed.
myTool --help
## options\_man | --man
It displays the manual.
my $t = t->new_with_options();
$t->options_man();
This is automatically fired if the command option "--man" is passed.
myTool --man
## options\_short\_usage | --usage
It displays a short version of the help message.
my $t = t->new_with_options();
$t->options_short_usage($exit_code);
This is automatically fired if the command option "--usage" is passed.
myTool --usage
# IMPORT PARAMETERS
The list of parameters supported by [MooX::Options](https://metacpan.org/pod/MooX::Options).
## flavour
Passes extra arguments for [Getopt::Long::Descriptive](https://metacpan.org/pod/Getopt::Long::Descriptive). It is useful if you
want to configure [Getopt::Long](https://metacpan.org/pod/Getopt::Long).
use MooX::Options flavour => [qw( pass_through )];
Any flavour is passed to [Getopt::Long](https://metacpan.org/pod/Getopt::Long) as a configuration, check the doc to see what is possible.
## protect\_argv
By default, `@ARGV` is protected. If you want to do something else on it, use this option and it will change the real `@ARGV`.
use MooX::Options protect_argv => 0;
## skip\_options
If you have Role with options and you want to deactivate some of them, you can use this parameter.
In that case, the `option` keyword will just work like an `has`.
use MooX::Options skip_options => [qw/multi/];
## prefer\_commandline
By default, arguments passed to `new_with_options` have a higher priority than the command line options.
This parameter will give the command line an higher priority.
use MooX::Options prefer_commandline => 1;
## with\_config\_from\_file
This parameter will load [MooX::Options](https://metacpan.org/pod/MooX::Options) in your module.
The config option will be used between the command line and parameters.
myTool :
use MooX::Options with_config_from_file => 1;
In /etc/myTool.json
{"test" : 1}
## with\_locale\_textdomain\_oo
This Parameter will load [MooX::Locale::TextDomain::OO](https://metacpan.org/pod/MooX::Locale::TextDomain::OO) into your module as
well as into [MooX::Options::Descriptive::Usage](https://metacpan.org/pod/MooX::Options::Descriptive::Usage).
No further action is taken, no language is chosen - everything keep in
control.
Please read [Locale::TextDomain::OO](https://metacpan.org/pod/Locale::TextDomain::OO) carefully how to enable the desired
translation setup accordingly.
# usage\_string
This parameter is passed to Getopt::Long::Descriptive::describe\_options() as
the first parameter.
It is a "sprintf"-like string that is used in generating the first line of the
usage message. It's a one-line summary of how the command is to be invoked.
The default value is "USAGE: %c %o".
%c will be replaced with what Getopt::Long::Descriptive thinks is the
program name (it's computed from $0, see "prog\_name").
%o will be replaced with a list of the short options, as well as the text
"\[long options...\]" if any have been defined.
The rest of the usage description can be used to summarize what arguments
are expected to follow the program's options, and is entirely free-form.
Literal "%" characters will need to be written as "%%", just like with
"sprintf".
## spacer
This indicate the char to use for spacer. Please only use 1 char otherwize the text will be too long.
The default char is " ".
use MooX::Options space => '+'
Then the "spacer\_before" and "spacer\_after" will use it for "man" and "help" message.
option 'x' => (is => 'ro', spacer_before => 1, spacer_after => 1);
# OPTION PARAMETERS
The keyword `option` extend the keyword `has` with specific parameters for the command line.
## doc | documentation
Documentation for the command line option.
## long\_doc
Documentation for the man page. By default the `doc` parameter will be used.
See also [Man parameters](https://metacpan.org/pod/MooX::Options::Manual::Man) to get more examples how to build a nice man page.
## required
This attribute indicates that the parameter is mandatory.
This attribute is not really used by [MooX::Options](https://metacpan.org/pod/MooX::Options) but ensures that consistent error message will be displayed.
## format
Format of the params, same as [Getopt::Long::Descriptive](https://metacpan.org/pod/Getopt::Long::Descriptive).
- i : integer
- i@: array of integer
- s : string
- s@: array of string
- f : float value
By default, it's a boolean value.
Take a look of available formats with [Getopt::Long::Descriptive](https://metacpan.org/pod/Getopt::Long::Descriptive).
You need to understand that everything is explicit here.
If you use [Moose](https://metacpan.org/pod/Moose) and your attribute has `isa => 'Array[Int]'`, that will **not** imply the format `i@`.
## format json : special format support
The parameter will be treated like a json string.
option 'hash' => (is => 'ro', json => 1);
You can also use the json format
option 'hash' => (is => 'ro', format => "json");
myTool --hash='{"a":1,"b":2}' # hash = { a => 1, b => 2 }
## negatable
It adds the negative version for the option.
option 'verbose' => (is => 'ro', negatable => 1);
myTool --verbose # verbose = 1
myTool --no-verbose # verbose = 0
The former name of this flag, negativable, is discouraged - since it's not a word.
## repeatable
It appends to the ["format"](#format) the array attribute `@`.
I advise to add a default value to your attribute to always have an array.
Otherwise the default value will be an undefined value.
option foo => (is => 'rw', format => 's@', default => sub { [] });
myTool --foo="abc" --foo="def" # foo = ["abc", "def"]
## autosplit
For repeatable option, you can add the autosplit feature with your specific parameters.
option test => (is => 'ro', format => 'i@', default => sub {[]}, autosplit => ',');
myTool --test=1 --test=2 # test = (1, 2)
myTool --test=1,2,3 # test = (1, 2, 3)
It will also handle quoted params with the autosplit.
option testStr => (is => 'ro', format => 's@', default => sub {[]}, autosplit => ',');
myTool --testStr='a,b,"c,d",e,f' # testStr ("a", "b", "c,d", "e", "f")
## autorange
For another repeatable option you can add the autorange feature with your specific parameters. This
allows you to pass number ranges instead of passing each individual number.
option test => (is => 'ro', format => 'i@', default => sub {[]}, autorange => 1);
myTool --test=1 --test=2 # test = (1, 2)
myTool --test=1,2,3 # test = (1, 2, 3)
myTool --test=1,2,3..6 # test = (1, 2, 3, 4, 5, 6)
It will also handle quoted params like `autosplit`, and will not rangify them.
option testStr => (is => 'ro', format => 's@', default => sub {[]}, autorange => 1);
myTool --testStr='1,2,"3,a,4",5' # testStr (1, 2, "3,a,4", 5)
`autosplit` will be set to ',' if undefined. You may set `autosplit` to a different delimiter than ','
for your group separation, but the range operator '..' cannot be changed.
option testStr => (is => 'ro', format => 's@', default => sub {[]}, autorange => 1, autosplit => '-');
myTool --testStr='1-2-3-5..7' # testStr (1, 2, 3, 5, 6, 7)
## short
Long option can also have short version or aliased.
option 'verbose' => (is => 'ro', short => 'v');
myTool --verbose # verbose = 1
myTool -v # verbose = 1
option 'account_id' => (is => 'ro', format => 'i', short => 'a|id');
myTool --account_id=1
myTool -a=1
myTool --id=1
You can also use a shorter option without attribute :
option 'account_id' => (is => 'ro', format => 'i');
myTool --acc=1
myTool --account=1
## order
Specifies the order of the attribute. If you want to push some attributes at the end of the list.
By default all options have an order set to `0`, and options are sorted by their names.
option 'at_the_end' => (is => 'ro', order => 999);
## hidden
Hide option from doc but still an option you can use on command line.
option 'debug' => (is => 'ro', doc => 'hidden');
Or
option 'debug' => (is => 'ro', hidden => 1);
## spacer\_before, spacer\_after
Add spacer before or after or both the params
option 'myoption' => (is => 'ro', spacer_before => 1, spacer_after => 1);
# ADDITIONAL MANUALS
- [Man parameters](https://metacpan.org/pod/MooX::Options::Manual::Man)
- [Using namespace::clean](https://metacpan.org/pod/MooX::Options::Manual::NamespaceClean)
- [Manage your tools with MooX::Cmd](https://metacpan.org/pod/MooX::Options::Manual::MooXCmd)
# EXTERNAL EXAMPLES
- [Slide3D about MooX::Options](http://perltalks.celogeek.com/slides/2012/08/moox-options-slide3d.html)
# Translation
Translation is now supported.
Use the dzil command to update the pot and merge into the po files.
- dzil msg-init
Create a new language po
- dzil msg-scan
Scan and generate or update the pot file
- dzil msg-merge
Update all languages using the pot file
## THANKS
- sschober
For implementation and German translation.
# THANKS
- Matt S. Trout (mst) <mst@shadowcat.co.uk>
For his patience and advice.
- Tomas Doran (t0m) <bobtfish@bobtfish.net>
To help me release the new version, and using it :)
- Torsten Raudssus (Getty)
to use it a lot in [DuckDuckGo](http://duckduckgo.com) (go to see [MooX](https://metacpan.org/pod/MooX) module also)
- Jens Rehsack (REHSACK)
Use with [PkgSrc](http://www.pkgsrc.org/), and many really good idea ([MooX::Cmd](https://metacpan.org/pod/MooX::Cmd), [MooX::Options](https://metacpan.org/pod/MooX::Options), and more to come I'm sure)
- All contributors
For improving and add more feature to MooX::Options
# SUPPORT
You can find documentation for this module with the perldoc command.
perldoc MooX::Options
You can also look for information at:
- RT: CPAN's request tracker (report bugs here)
[http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooX-Options](http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooX-Options)
- AnnoCPAN: Annotated CPAN documentation
[http://annocpan.org/dist/MooX-Options](http://annocpan.org/dist/MooX-Options)
- CPAN Ratings
[http://cpanratings.perl.org/d/MooX-Options](http://cpanratings.perl.org/d/MooX-Options)
- Search CPAN
[http://search.cpan.org/dist/MooX-Options/](http://search.cpan.org/dist/MooX-Options/)
# AUTHOR
celogeek <me@celogeek.com>
# COPYRIGHT AND LICENSE
This software is copyright (c) 2013 by celogeek <me@celogeek.com>.
This software is copyright (c) 2017 by Jens Rehsack.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.