2 package MooseX::Getopt;
5 use Moose::Util::TypeConstraints;
7 use MooseX::Getopt::OptionTypeMap;
9 use MooseX::Getopt::Session;
11 use MooseX::Getopt::Meta::Attribute;
12 use MooseX::Getopt::Meta::Attribute::NoGetopt;
15 our $VERSION = '0.15';
16 our $AUTHORITY = 'cpan:STEVAN';
19 use constant _default_getopt_session => 'MooseX::Getopt::Session';
25 metaclass => 'NoGetopt',
31 metaclass => 'NoGetopt',
36 isa => 'MooseX::Getopt::Session',
37 metaclass => 'NoGetopt',
41 sub new_with_options {
44 Moose->throw_error("Single parameters to new_with_options() must be a HASH ref")
45 if ref $_[0] and ref $_ ne 'HASH';
47 my %params = ( @_ == 1 ? %{ $_[0] } : @_ );
49 my $getopt = defined $params{getopt}
51 : $class->_default_getopt_session->new(
52 classes_filter => sub { $_ eq $class }
55 my %options = $getopt->options;
58 ARGV => [ $getopt->argv ], # backward compatibility
59 extra_argv => [ $getopt->extra_argv ], # backward compatibility
61 %params, # explicit params to ->new
62 %options, # params from CLI
67 sub _compute_getopt_attrs {
71 $_->does('MooseX::Getopt::Meta::Attribute::Trait')
75 !$_->does('MooseX::Getopt::Meta::Attribute::Trait::NoGetopt')
76 } $class->meta->compute_all_applicable_attributes;
88 MooseX::Getopt - A Moose role for processing command line options
96 with 'MooseX::Getopt';
98 has 'out' => (is => 'rw', isa => 'Str', required => 1);
99 has 'in' => (is => 'rw', isa => 'Str', required => 1);
101 # ... rest of the class here
108 my $app = My::App->new_with_options();
109 # ... rest of the script here
111 ## on the command line
112 % perl my_app_script.pl -in file.input -out file.dump
116 This is a role which provides an alternate constructor for creating
117 objects using parameters passed in from the command line.
119 This module attempts to DWIM as much as possible with the command line
120 params by introspecting your class's attributes. It will use the name
121 of your attribute as the command line option, and if there is a type
122 constraint defined, it will configure Getopt::Long to handle the option
125 You can use the trait L<MooseX::Getopt::Meta::Attribute::Trait> or the
126 attribute metaclass L<MooseX::Getopt::Meta::Attribute> to get non-default
127 commandline option names and aliases.
129 You can use the trait L<MooseX::Getopt::Meta::Attribute::Trait::NoGetopt>
130 or the attribute metaclass L<MooseX::Getopt::Meta::Attribute::NoGetopt>
131 to have C<MooseX::Getopt> ignore your attribute in the commandline options.
133 By default, attributes which start with an underscore are not given
134 commandline argument support, unless the attribute's metaclass is set
135 to L<MooseX::Getopt::Meta::Attribute>. If you don't want you accessors
136 to have the leading underscore in thier name, you can do this:
138 # for read/write attributes
139 has '_foo' => (accessor => 'foo', ...);
141 # or for read-only attributes
142 has '_bar' => (reader => 'bar', ...);
144 This will mean that Getopt will not handle a --foo param, but your
145 code can still call the C<foo> method.
147 If your class also uses a configfile-loading role based on
148 L<MooseX::ConfigFromFile>, such as L<MooseX::SimpleConfig>,
149 L<MooseX::Getopt>'s C<new_with_options> will load the configfile
150 specified by the C<--configfile> option (or the default you've
151 given for the configfile attribute) for you.
153 Options specified in multiple places follow the following
154 precendence order: commandline overrides configfile, which
155 overrides explicit new_with_options parameters.
157 =head2 Supported Type Constraints
163 A I<Bool> type constraint is set up as a boolean option with
164 Getopt::Long. So that this attribute description:
166 has 'verbose' => (is => 'rw', isa => 'Bool');
168 would translate into C<verbose!> as a Getopt::Long option descriptor,
169 which would enable the following command line options:
171 % my_script.pl --verbose
172 % my_script.pl --noverbose
174 =item I<Int>, I<Float>, I<Str>
176 These type constraints are set up as properly typed options with
177 Getopt::Long, using the C<=i>, C<=f> and C<=s> modifiers as appropriate.
181 An I<ArrayRef> type constraint is set up as a multiple value option
182 in Getopt::Long. So that this attribute description:
187 default => sub { [] }
190 would translate into C<includes=s@> as a Getopt::Long option descriptor,
191 which would enable the following command line options:
193 % my_script.pl --include /usr/lib --include /usr/local/lib
197 A I<HashRef> type constraint is set up as a hash value option
198 in Getopt::Long. So that this attribute description:
203 default => sub { {} }
206 would translate into C<define=s%> as a Getopt::Long option descriptor,
207 which would enable the following command line options:
209 % my_script.pl --define os=linux --define vendor=debian
213 =head2 Custom Type Constraints
215 It is possible to create custom type constraint to option spec
216 mappings if you need them. The process is fairly simple (but a
217 little verbose maybe). First you create a custom subtype, like
220 subtype 'ArrayOfInts'
222 => where { scalar (grep { looks_like_number($_) } @$_) };
224 Then you register the mapping, like so:
226 MooseX::Getopt::OptionTypeMap->add_option_type_to_map(
227 'ArrayOfInts' => '=i@'
230 Now any attribute declarations using this type constraint will
231 get the custom option spec. So that, this:
235 isa => 'ArrayOfInts',
236 default => sub { [0] }
239 Will translate to the following on the command line:
241 % my_script.pl --nums 5 --nums 88 --nums 199
243 This example is fairly trivial, but more complex validations are
244 easily possible with a little creativity. The trick is balancing
245 the type constraint validations with the Getopt::Long validations.
247 Better examples are certainly welcome :)
249 =head2 Inferred Type Constraints
251 If you define a custom subtype which is a subtype of one of the
252 standard L</Supported Type Constraints> above, and do not explicitly
253 provide custom support as in L</Custom Type Constraints> above,
254 MooseX::Getopt will treat it like the parent type for Getopt
257 For example, if you had the same custom C<ArrayOfInts> subtype
258 from the examples above, but did not add a new custom option
259 type for it to the C<OptionTypeMap>, it would be treated just
260 like a normal C<ArrayRef> type for Getopt purposes (that is,
267 =item B<new_with_options (%params)>
269 This method will take a set of default C<%params> and then collect
270 params from the command line (possibly overriding those in C<%params>)
271 and then return a newly constructed object.
273 If L<Getopt::Long/GetOptions> fails (due to invalid arguments),
274 C<new_with_options> will throw an exception.
276 If you have L<Getopt::Long::Descriptive> a the C<usage> param is also passed to
281 This accessor contains a reference to a copy of the C<@ARGV> array
282 as it originally existed at the time of C<new_with_options>.
286 This accessor contains an arrayref of leftover C<@ARGV> elements that
287 L<Getopt::Long> did not parse. Note that the real C<@ARGV> is left
292 This returns the role meta object.
298 All complex software has bugs lurking in it, and this module is no
299 exception. If you find a bug please either email me, or add the bug
304 Stevan Little E<lt>stevan@iinteractive.comE<gt>
306 Brandon L. Black, E<lt>blblack@gmail.comE<gt>
308 Yuval Kogman, E<lt>nothingmuch@woobling.orgE<gt>
312 Ryan D Johnson, E<lt>ryan@innerfence.comE<gt>
314 =head1 COPYRIGHT AND LICENSE
316 Copyright 2007-2008 by Infinity Interactive, Inc.
318 L<http://www.iinteractive.com>
320 This library is free software; you can redistribute it and/or modify
321 it under the same terms as Perl itself.