1# NAME 2 3MooX::Options - Explicit Options eXtension for Object Class 4 5# SYNOPSIS 6 7In myOptions.pm : 8 9 package myOptions; 10 use Moo; 11 use MooX::Options; 12 13 option 'show_this_file' => ( 14 is => 'ro', 15 format => 's', 16 required => 1, 17 doc => 'the file to display' 18 ); 19 1; 20 21In myTool.pl : 22 23 use myOptions; 24 use Path::Class; 25 26 my $opt = myOptions->new_with_options; 27 28 print "Content of the file : ", 29 file($opt->show_this_file)->slurp; 30 31To use it : 32 33 perl myTool.pl --show_this_file=myFile.txt 34 Content of the file: myFile content 35 36The help message : 37 38 perl myTool.pl --help 39 USAGE: myTool.pl [-h] [long options...] 40 41 --show_this_file: String 42 the file to display 43 44 -h --help: 45 show this help message 46 47 --man: 48 show the manual 49 50The usage message : 51 52 perl myTool.pl --usage 53 USAGE: myTool.pl [ --show_this_file=String ] [ --usage ] [ --help ] [ --man ] 54 55The manual : 56 57 perl myTool.pl --man 58 59# DESCRIPTION 60 61Create 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. 62 63Everything is explicit. You have an `option` keyword to replace the usual `has` to explicitly use your attribute into the command line. 64 65The `option` keyword takes additional parameters and uses [Getopt::Long::Descriptive](https://metacpan.org/pod/Getopt::Long::Descriptive) 66to generate a command line tool. 67 68# IMPORTANT CHANGES IN 4.100 69 70## Enhancing existing attributes 71 72One can now convert an existing attribute into an option for obvious reasons. 73 74 package CommonRole; 75 76 use Moo::Role; 77 78 has attr => (is => "ro", ...); 79 80 sub common_logic { ... } 81 82 1; 83 84 package Suitable::Cmd::CLI; 85 86 use Moo; 87 use MooX::Cmd; 88 use MooX::Options; 89 90 with "CommonRole"; 91 92 option '+attr' => (format => 's', repeatable => 1); 93 94 sub execute { shift->common_logic } 95 96 1; 97 98 package Suitable::Web::Request::Handler; 99 100 use Moo; 101 102 with "CommonRole"; 103 104 sub all_suits { shift->common_logic } 105 106 1; 107 108 package Suitable::Web; 109 110 use Dancer2; 111 use Suitable::Web::Request::Handler; 112 113 set serializer => "JSON"; 114 115 get '/suits' => sub { 116 $my $reqh = Suitable::Web::Request::Handler->new( attr => config->{suit_attr} ); 117 $reqh->all_suits; 118 }; 119 120 dance; 121 122 1; 123 124Of course there more ways to to it, [Jedi](https://metacpan.org/pod/Jedi) or [Catalyst](https://metacpan.org/pod/Catalyst) shall be fine, either. 125 126## Rename negativable into negatable 127 128Since users stated that `negativable` is not a reasonable word, the flag is 129renamed into negatable. Those who will 2020 continue use negativable might 130or might not be warned about soon depreciation. 131 132## Replace Locale::TextDomain by MooX::Locale::Passthrough 133 134[Locale::TextDomain](https://metacpan.org/pod/Locale::TextDomain) is broken (technically and functionally) and causes a 135lot of people to avoid `MooX::Options` or hack around. Both is unintened. 136 137So introduce [MooX::Locale::Passthrough](https://metacpan.org/pod/MooX::Locale::Passthrough) to allow any vendor to add reasonable 138localization, eg. by composing [MooX::Locale::TextDomain::OO](https://metacpan.org/pod/MooX::Locale::TextDomain::OO) into it's 139solution and initialize the localization in a reasonable way. 140 141## Make lazy loaded features optional 142 143Since some features aren't used on a regular basis, their dependencies have 144been downgraded to `recommended` or `suggested`. The optional features are: 145 146- autosplit 147 148 This feature allowes one to split option arguments at a defined character and 149 always return an array (implicit flag `repeatable`). 150 151 option "search_path" => ( is => "ro", required => 1, autosplit => ":", format => "s" ); 152 153 However, this feature requires following modules are provided: 154 155 - [Data::Record](https://metacpan.org/pod/Data::Record) 156 - [Regexp::Common](https://metacpan.org/pod/Regexp::Common) 157 158- json format 159 160 This feature allowes one to invoke a script like 161 162 $ my-tool --json-attr '{ "gem": "sapphire", "color": "blue" }' 163 164 It might be a reasonable enhancement to _handles_. 165 166 Handling JSON formatted arguments requires any of those modules 167 are loded: 168 169 - [JSON::MaybeXS](https://metacpan.org/pod/JSON::MaybeXS) 170 - [JSON::PP](https://metacpan.org/pod/JSON::PP) (in Core since 5.14). 171 172## Decouple autorange and autosplit 173 174Until 4.023, any option which had autorange enabled got autosplit enabled, too. 175Since autosplit might not work correctly and for a reasonable amount of users 176the fact of 177 178 $ my-tool --range 1..5 179 180is all they desire, autosplit will enabled only when the dependencies of 181autosplit are fulfilled. 182 183# IMPORTED METHODS 184 185The list of the methods automatically imported into your class. 186 187## new\_with\_options 188 189It will parse your command line params and your inline params, validate and call the `new` method. 190 191 myTool --str=ko 192 193 t->new_with_options()->str # ko 194 t->new_with_options(str => 'ok')->str #ok 195 196## option 197 198The `option` keyword replaces the `has` method and adds support for special options for the command line only. 199 200See ["OPTION PARAMETERS"](#option-parameters) for the documentation. 201 202## options\_usage | --help 203 204It displays the usage message and returns the exit code. 205 206 my $t = t->new_with_options(); 207 my $exit_code = 1; 208 my $pre_message = "str is not valid"; 209 $t->options_usage($exit_code, $pre_message); 210 211This method is also automatically fired if the command option "--help" is passed. 212 213 myTool --help 214 215## options\_man | --man 216 217It displays the manual. 218 219 my $t = t->new_with_options(); 220 $t->options_man(); 221 222This is automatically fired if the command option "--man" is passed. 223 224 myTool --man 225 226## options\_short\_usage | --usage 227 228It displays a short version of the help message. 229 230 my $t = t->new_with_options(); 231 $t->options_short_usage($exit_code); 232 233This is automatically fired if the command option "--usage" is passed. 234 235 myTool --usage 236 237# IMPORT PARAMETERS 238 239The list of parameters supported by [MooX::Options](https://metacpan.org/pod/MooX::Options). 240 241## flavour 242 243Passes extra arguments for [Getopt::Long::Descriptive](https://metacpan.org/pod/Getopt::Long::Descriptive). It is useful if you 244want to configure [Getopt::Long](https://metacpan.org/pod/Getopt::Long). 245 246 use MooX::Options flavour => [qw( pass_through )]; 247 248Any flavour is passed to [Getopt::Long](https://metacpan.org/pod/Getopt::Long) as a configuration, check the doc to see what is possible. 249 250## protect\_argv 251 252By default, `@ARGV` is protected. If you want to do something else on it, use this option and it will change the real `@ARGV`. 253 254 use MooX::Options protect_argv => 0; 255 256## skip\_options 257 258If you have Role with options and you want to deactivate some of them, you can use this parameter. 259In that case, the `option` keyword will just work like an `has`. 260 261 use MooX::Options skip_options => [qw/multi/]; 262 263## prefer\_commandline 264 265By default, arguments passed to `new_with_options` have a higher priority than the command line options. 266 267This parameter will give the command line an higher priority. 268 269 use MooX::Options prefer_commandline => 1; 270 271## with\_config\_from\_file 272 273This parameter will load [MooX::Options](https://metacpan.org/pod/MooX::Options) in your module. 274The config option will be used between the command line and parameters. 275 276myTool : 277 278 use MooX::Options with_config_from_file => 1; 279 280In /etc/myTool.json 281 282 {"test" : 1} 283 284## with\_locale\_textdomain\_oo 285 286This Parameter will load [MooX::Locale::TextDomain::OO](https://metacpan.org/pod/MooX::Locale::TextDomain::OO) into your module as 287well as into [MooX::Options::Descriptive::Usage](https://metacpan.org/pod/MooX::Options::Descriptive::Usage). 288 289No further action is taken, no language is chosen - everything keep in 290control. 291 292Please read [Locale::TextDomain::OO](https://metacpan.org/pod/Locale::TextDomain::OO) carefully how to enable the desired 293translation setup accordingly. 294 295# usage\_string 296 297This parameter is passed to Getopt::Long::Descriptive::describe\_options() as 298the first parameter. 299 300It is a "sprintf"-like string that is used in generating the first line of the 301usage message. It's a one-line summary of how the command is to be invoked. 302The default value is "USAGE: %c %o". 303 304%c will be replaced with what Getopt::Long::Descriptive thinks is the 305program name (it's computed from $0, see "prog\_name"). 306 307%o will be replaced with a list of the short options, as well as the text 308"\[long options...\]" if any have been defined. 309 310The rest of the usage description can be used to summarize what arguments 311are expected to follow the program's options, and is entirely free-form. 312 313Literal "%" characters will need to be written as "%%", just like with 314"sprintf". 315 316## spacer 317 318This indicate the char to use for spacer. Please only use 1 char otherwize the text will be too long. 319 320The default char is " ". 321 322 use MooX::Options space => '+' 323 324Then the "spacer\_before" and "spacer\_after" will use it for "man" and "help" message. 325 326 option 'x' => (is => 'ro', spacer_before => 1, spacer_after => 1); 327 328# OPTION PARAMETERS 329 330The keyword `option` extend the keyword `has` with specific parameters for the command line. 331 332## doc | documentation 333 334Documentation for the command line option. 335 336## long\_doc 337 338Documentation for the man page. By default the `doc` parameter will be used. 339 340See also [Man parameters](https://metacpan.org/pod/MooX::Options::Manual::Man) to get more examples how to build a nice man page. 341 342## required 343 344This attribute indicates that the parameter is mandatory. 345This attribute is not really used by [MooX::Options](https://metacpan.org/pod/MooX::Options) but ensures that consistent error message will be displayed. 346 347## format 348 349Format of the params, same as [Getopt::Long::Descriptive](https://metacpan.org/pod/Getopt::Long::Descriptive). 350 351- i : integer 352- i@: array of integer 353- s : string 354- s@: array of string 355- f : float value 356 357By default, it's a boolean value. 358 359Take a look of available formats with [Getopt::Long::Descriptive](https://metacpan.org/pod/Getopt::Long::Descriptive). 360 361You need to understand that everything is explicit here. 362If you use [Moose](https://metacpan.org/pod/Moose) and your attribute has `isa => 'Array[Int]'`, that will **not** imply the format `i@`. 363 364## format json : special format support 365 366The parameter will be treated like a json string. 367 368 option 'hash' => (is => 'ro', json => 1); 369 370You can also use the json format 371 372 option 'hash' => (is => 'ro', format => "json"); 373 374 myTool --hash='{"a":1,"b":2}' # hash = { a => 1, b => 2 } 375 376## negatable 377 378It adds the negative version for the option. 379 380 option 'verbose' => (is => 'ro', negatable => 1); 381 382 myTool --verbose # verbose = 1 383 myTool --no-verbose # verbose = 0 384 385The former name of this flag, negativable, is discouraged - since it's not a word. 386 387## repeatable 388 389It appends to the ["format"](#format) the array attribute `@`. 390 391I advise to add a default value to your attribute to always have an array. 392Otherwise the default value will be an undefined value. 393 394 option foo => (is => 'rw', format => 's@', default => sub { [] }); 395 396 myTool --foo="abc" --foo="def" # foo = ["abc", "def"] 397 398## autosplit 399 400For repeatable option, you can add the autosplit feature with your specific parameters. 401 402 option test => (is => 'ro', format => 'i@', default => sub {[]}, autosplit => ','); 403 404 myTool --test=1 --test=2 # test = (1, 2) 405 myTool --test=1,2,3 # test = (1, 2, 3) 406 407 408It will also handle quoted params with the autosplit. 409 410 option testStr => (is => 'ro', format => 's@', default => sub {[]}, autosplit => ','); 411 412 myTool --testStr='a,b,"c,d",e,f' # testStr ("a", "b", "c,d", "e", "f") 413 414## autorange 415 416For another repeatable option you can add the autorange feature with your specific parameters. This 417allows you to pass number ranges instead of passing each individual number. 418 419 option test => (is => 'ro', format => 'i@', default => sub {[]}, autorange => 1); 420 421 myTool --test=1 --test=2 # test = (1, 2) 422 myTool --test=1,2,3 # test = (1, 2, 3) 423 myTool --test=1,2,3..6 # test = (1, 2, 3, 4, 5, 6) 424 425 426It will also handle quoted params like `autosplit`, and will not rangify them. 427 428 option testStr => (is => 'ro', format => 's@', default => sub {[]}, autorange => 1); 429 430 myTool --testStr='1,2,"3,a,4",5' # testStr (1, 2, "3,a,4", 5) 431 432`autosplit` will be set to ',' if undefined. You may set `autosplit` to a different delimiter than ',' 433for your group separation, but the range operator '..' cannot be changed. 434 435 option testStr => (is => 'ro', format => 's@', default => sub {[]}, autorange => 1, autosplit => '-'); 436 437 myTool --testStr='1-2-3-5..7' # testStr (1, 2, 3, 5, 6, 7) 438 439## short 440 441Long option can also have short version or aliased. 442 443 option 'verbose' => (is => 'ro', short => 'v'); 444 445 myTool --verbose # verbose = 1 446 myTool -v # verbose = 1 447 448 option 'account_id' => (is => 'ro', format => 'i', short => 'a|id'); 449 450 myTool --account_id=1 451 myTool -a=1 452 myTool --id=1 453 454You can also use a shorter option without attribute : 455 456 option 'account_id' => (is => 'ro', format => 'i'); 457 458 myTool --acc=1 459 myTool --account=1 460 461## order 462 463Specifies the order of the attribute. If you want to push some attributes at the end of the list. 464By default all options have an order set to `0`, and options are sorted by their names. 465 466 option 'at_the_end' => (is => 'ro', order => 999); 467 468## hidden 469 470Hide option from doc but still an option you can use on command line. 471 472 option 'debug' => (is => 'ro', doc => 'hidden'); 473 474Or 475 476 option 'debug' => (is => 'ro', hidden => 1); 477 478## spacer\_before, spacer\_after 479 480Add spacer before or after or both the params 481 482 option 'myoption' => (is => 'ro', spacer_before => 1, spacer_after => 1); 483 484# ADDITIONAL MANUALS 485 486- [Man parameters](https://metacpan.org/pod/MooX::Options::Manual::Man) 487- [Using namespace::clean](https://metacpan.org/pod/MooX::Options::Manual::NamespaceClean) 488- [Manage your tools with MooX::Cmd](https://metacpan.org/pod/MooX::Options::Manual::MooXCmd) 489 490# EXTERNAL EXAMPLES 491 492- [Slide3D about MooX::Options](http://perltalks.celogeek.com/slides/2012/08/moox-options-slide3d.html) 493 494# Translation 495 496Translation is now supported. 497 498Use the dzil command to update the pot and merge into the po files. 499 500- dzil msg-init 501 502 Create a new language po 503 504- dzil msg-scan 505 506 Scan and generate or update the pot file 507 508- dzil msg-merge 509 510 Update all languages using the pot file 511 512## THANKS 513 514- sschober 515 516 For implementation and German translation. 517 518# THANKS 519 520- Matt S. Trout (mst) <mst@shadowcat.co.uk> 521 522 For his patience and advice. 523 524- Tomas Doran (t0m) <bobtfish@bobtfish.net> 525 526 To help me release the new version, and using it :) 527 528- Torsten Raudssus (Getty) 529 530 to use it a lot in [DuckDuckGo](http://duckduckgo.com) (go to see [MooX](https://metacpan.org/pod/MooX) module also) 531 532- Jens Rehsack (REHSACK) 533 534 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) 535 536- All contributors 537 538 For improving and add more feature to MooX::Options 539 540# SUPPORT 541 542You can find documentation for this module with the perldoc command. 543 544 perldoc MooX::Options 545 546You can also look for information at: 547 548- RT: CPAN's request tracker (report bugs here) 549 550 [http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooX-Options](http://rt.cpan.org/NoAuth/Bugs.html?Dist=MooX-Options) 551 552- AnnoCPAN: Annotated CPAN documentation 553 554 [http://annocpan.org/dist/MooX-Options](http://annocpan.org/dist/MooX-Options) 555 556- CPAN Ratings 557 558 [http://cpanratings.perl.org/d/MooX-Options](http://cpanratings.perl.org/d/MooX-Options) 559 560- Search CPAN 561 562 [http://search.cpan.org/dist/MooX-Options/](http://search.cpan.org/dist/MooX-Options/) 563 564# AUTHOR 565 566celogeek <me@celogeek.com> 567 568# COPYRIGHT AND LICENSE 569 570This software is copyright (c) 2013 by celogeek <me@celogeek.com>. 571 572This software is copyright (c) 2017 by Jens Rehsack. 573 574This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. 575