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