* MooseX::Getopt: ARGV and extra_argv are deletaged from MooseX::Getopt::Session.
[gitmo/MooseX-Getopt.git] / lib / MooseX / Getopt.pm
CommitLineData
5dac17c3 1
2package MooseX::Getopt;
3use Moose::Role;
4
550da402 5use Moose::Util::TypeConstraints;
6
8034a232 7use MooseX::Getopt::OptionTypeMap;
550da402 8
c6c1f628 9use MooseX::Getopt::Session;
550da402 10
5dac17c3 11use MooseX::Getopt::Meta::Attribute;
0f8232b6 12use MooseX::Getopt::Meta::Attribute::NoGetopt;
5dac17c3 13
75a6449b 14
e4ab19b9 15our $VERSION = '0.15';
8034a232 16our $AUTHORITY = 'cpan:STEVAN';
17
550da402 18
c6c1f628 19use constant _default_getopt_session => 'MooseX::Getopt::Session';
20
21
c6c1f628 22has getopt => (
550da402 23 is => 'rw',
c6c1f628 24 isa => 'MooseX::Getopt::Session',
550da402 25 metaclass => 'NoGetopt',
ac2073c8 26 handles => [ 'ARGV', 'extra_argv' ],
550da402 27);
3899e5df 28
ee211848 29
c6c1f628 30sub new_with_options {
31 my $class = shift;
6bb4cb66 32
c6c1f628 33 Moose->throw_error("Single parameters to new_with_options() must be a HASH ref")
34 if ref $_[0] and ref $_ ne 'HASH';
75a6449b 35
c6c1f628 36 my %params = ( @_ == 1 ? %{ $_[0] } : @_ );
6bb4cb66 37
c6c1f628 38 my $getopt = defined $params{getopt}
39 ? $params{getopt}
c7ecf9ea 40 : $class->_default_getopt_session->new(
ac2073c8 41 classes_filter => sub { $_ eq $class },
42 params => \%params,
43 );
ee211848 44
c6c1f628 45 $class->new(
c6c1f628 46 getopt => $getopt,
053fa19e 47 %{ $getopt->params }, # params from session object
48 %params, # explicit params to ->new
ac2073c8 49 %{ $getopt->options }, # params from CLI
ee211848 50 );
c6c1f628 51};
0e715336 52
0e715336 53
bff3807b 54sub _compute_getopt_attrs {
55 my $class = shift;
c6c1f628 56
57 return grep {
58 $_->does('MooseX::Getopt::Meta::Attribute::Trait')
bff3807b 59 or
60 $_->name !~ /^_/
adbe3e57 61 } grep {
62 !$_->does('MooseX::Getopt::Meta::Attribute::Trait::NoGetopt')
c6c1f628 63 } $class->meta->compute_all_applicable_attributes;
64};
4ad81caf 65
5dac17c3 66
8034a232 67no Moose::Role; 1;
5dac17c3 68
69__END__
70
71=pod
72
73=head1 NAME
74
8034a232 75MooseX::Getopt - A Moose role for processing command line options
5dac17c3 76
77=head1 SYNOPSIS
78
4e086633 79 ## In your class
5dac17c3 80 package My::App;
81 use Moose;
4e086633 82
5dac17c3 83 with 'MooseX::Getopt';
4e086633 84
5dac17c3 85 has 'out' => (is => 'rw', isa => 'Str', required => 1);
86 has 'in' => (is => 'rw', isa => 'Str', required => 1);
4e086633 87
5dac17c3 88 # ... rest of the class here
4e086633 89
5dac17c3 90 ## in your script
91 #!/usr/bin/perl
4e086633 92
5dac17c3 93 use My::App;
4e086633 94
5dac17c3 95 my $app = My::App->new_with_options();
96 # ... rest of the script here
4e086633 97
5dac17c3 98 ## on the command line
99 % perl my_app_script.pl -in file.input -out file.dump
100
101=head1 DESCRIPTION
102
4e086633 103This is a role which provides an alternate constructor for creating
104objects using parameters passed in from the command line.
8034a232 105
4e086633 106This module attempts to DWIM as much as possible with the command line
107params by introspecting your class's attributes. It will use the name
108of your attribute as the command line option, and if there is a type
8034a232 109constraint defined, it will configure Getopt::Long to handle the option
3899e5df 110accordingly.
111
2814de27 112You can use the trait L<MooseX::Getopt::Meta::Attribute::Trait> or the
113attribute metaclass L<MooseX::Getopt::Meta::Attribute> to get non-default
114commandline option names and aliases.
3899e5df 115
2814de27 116You can use the trait L<MooseX::Getopt::Meta::Attribute::Trait::NoGetopt>
117or the attribute metaclass L<MooseX::Getopt::Meta::Attribute::NoGetopt>
0f8232b6 118to have C<MooseX::Getopt> ignore your attribute in the commandline options.
119
3899e5df 120By default, attributes which start with an underscore are not given
121commandline argument support, unless the attribute's metaclass is set
3d9a716d 122to L<MooseX::Getopt::Meta::Attribute>. If you don't want you accessors
123to have the leading underscore in thier name, you can do this:
124
125 # for read/write attributes
126 has '_foo' => (accessor => 'foo', ...);
4e086633 127
3d9a716d 128 # or for read-only attributes
4e086633 129 has '_bar' => (reader => 'bar', ...);
3d9a716d 130
4e086633 131This will mean that Getopt will not handle a --foo param, but your
132code can still call the C<foo> method.
8034a232 133
ee69c4ba 134If your class also uses a configfile-loading role based on
135L<MooseX::ConfigFromFile>, such as L<MooseX::SimpleConfig>,
136L<MooseX::Getopt>'s C<new_with_options> will load the configfile
b4a79051 137specified by the C<--configfile> option (or the default you've
138given for the configfile attribute) for you.
139
140Options specified in multiple places follow the following
141precendence order: commandline overrides configfile, which
142overrides explicit new_with_options parameters.
ee69c4ba 143
8034a232 144=head2 Supported Type Constraints
145
146=over 4
147
148=item I<Bool>
149
4e086633 150A I<Bool> type constraint is set up as a boolean option with
8034a232 151Getopt::Long. So that this attribute description:
152
153 has 'verbose' => (is => 'rw', isa => 'Bool');
154
4e086633 155would translate into C<verbose!> as a Getopt::Long option descriptor,
8034a232 156which would enable the following command line options:
157
158 % my_script.pl --verbose
4e086633 159 % my_script.pl --noverbose
160
8034a232 161=item I<Int>, I<Float>, I<Str>
162
4e086633 163These type constraints are set up as properly typed options with
8034a232 164Getopt::Long, using the C<=i>, C<=f> and C<=s> modifiers as appropriate.
165
166=item I<ArrayRef>
167
168An I<ArrayRef> type constraint is set up as a multiple value option
169in Getopt::Long. So that this attribute description:
170
171 has 'include' => (
4e086633 172 is => 'rw',
173 isa => 'ArrayRef',
8034a232 174 default => sub { [] }
175 );
176
4e086633 177would translate into C<includes=s@> as a Getopt::Long option descriptor,
8034a232 178which would enable the following command line options:
179
180 % my_script.pl --include /usr/lib --include /usr/local/lib
181
182=item I<HashRef>
183
184A I<HashRef> type constraint is set up as a hash value option
185in Getopt::Long. So that this attribute description:
186
187 has 'define' => (
4e086633 188 is => 'rw',
189 isa => 'HashRef',
8034a232 190 default => sub { {} }
191 );
192
4e086633 193would translate into C<define=s%> as a Getopt::Long option descriptor,
8034a232 194which would enable the following command line options:
195
196 % my_script.pl --define os=linux --define vendor=debian
197
198=back
199
200=head2 Custom Type Constraints
201
4e086633 202It is possible to create custom type constraint to option spec
8034a232 203mappings if you need them. The process is fairly simple (but a
4e086633 204little verbose maybe). First you create a custom subtype, like
8034a232 205so:
206
207 subtype 'ArrayOfInts'
208 => as 'ArrayRef'
209 => where { scalar (grep { looks_like_number($_) } @$_) };
210
211Then you register the mapping, like so:
212
213 MooseX::Getopt::OptionTypeMap->add_option_type_to_map(
214 'ArrayOfInts' => '=i@'
215 );
216
4e086633 217Now any attribute declarations using this type constraint will
8034a232 218get the custom option spec. So that, this:
219
220 has 'nums' => (
221 is => 'ro',
222 isa => 'ArrayOfInts',
223 default => sub { [0] }
224 );
225
226Will translate to the following on the command line:
227
228 % my_script.pl --nums 5 --nums 88 --nums 199
229
4e086633 230This example is fairly trivial, but more complex validations are
8034a232 231easily possible with a little creativity. The trick is balancing
232the type constraint validations with the Getopt::Long validations.
233
234Better examples are certainly welcome :)
235
f63e6310 236=head2 Inferred Type Constraints
237
238If you define a custom subtype which is a subtype of one of the
239standard L</Supported Type Constraints> above, and do not explicitly
240provide custom support as in L</Custom Type Constraints> above,
241MooseX::Getopt will treat it like the parent type for Getopt
242purposes.
243
244For example, if you had the same custom C<ArrayOfInts> subtype
245from the examples above, but did not add a new custom option
246type for it to the C<OptionTypeMap>, it would be treated just
247like a normal C<ArrayRef> type for Getopt purposes (that is,
248C<=s@>).
249
ac2073c8 250=head2 Session
251
252L<MooseX::Getopt> can handle more than one class which contain
253attributes filled from CLI. In this case, you need to use explicite
254L<MooseX::Getopt::Session> object and then the Getopt attributes will be
255searched in any class which does L<MooseX::Getopt>.
256
257 package My::App;
258 use Moose;
259 with 'MooseX::Getopt';
260 has 'send' => (is => 'rw', predicate => 'has_send');
261
262 package My::App::Send;
263 use Moose;
264 with 'MooseX::Getopt';
265 has 'to' => (is => 'rw', isa => 'Str', default => 'localhost');
266 sub send { my $self = shift; warn "Sending mail to ", $self->to; }
267
268 # ... rest of the class here
269
270 ## in your script
271 #!/usr/bin/perl
272
273 my $getopt = MooseX::Getopt::Session->new;
274
275 my $app = My::App->new_with_options( getopt => $getopt );
276 if ($app->has_send) {
277 # Use the same command line
278 my $sender = My::App::Send->new_with_options( getopt => $getopt );
279 $sender->send;
280 }
281 # ... rest of the script here
282
283 ## on the command line
284 % perl my_app_script.pl --send --to server.example.net
285
5dac17c3 286=head1 METHODS
287
288=over 4
289
290=item B<new_with_options (%params)>
291
4e086633 292This method will take a set of default C<%params> and then collect
8034a232 293params from the command line (possibly overriding those in C<%params>)
294and then return a newly constructed object.
295
f63e6310 296If L<Getopt::Long/GetOptions> fails (due to invalid arguments),
297C<new_with_options> will throw an exception.
298
fad5da09 299If you have L<Getopt::Long::Descriptive> a the C<usage> param is also passed to
300C<new>.
301
3899e5df 302=item B<ARGV>
303
ac2073c8 304This accessor contains a reference to a copy of the C<@ARGV> array as it
305originally existed at the time of C<new_with_options>.
306
307The C<ARGV> is delegated from L<MooseX::Getopt::Session> object.
f63e6310 308
309=item B<extra_argv>
310
311This accessor contains an arrayref of leftover C<@ARGV> elements that
312L<Getopt::Long> did not parse. Note that the real C<@ARGV> is left
313un-mangled.
3899e5df 314
ac2073c8 315The C<extra_argv> is delegated from L<MooseX::Getopt::Session> object.
316
317=item B<getopt>
318
319This accessor contains a L<MooseX::Getopt::Session> object. This object can
320be shared between more than one class which does L<MooseX::Getopt>. The new
321object is created by default.
322
5dac17c3 323=item B<meta>
324
8034a232 325This returns the role meta object.
326
5dac17c3 327=back
328
ac2073c8 329=head1 SEE ALSO
330
331=over 4
332
333=item L<MooseX::Getopt::Strict>
334
335=item L<MooseX::Getopt::Session>
336
337=item L<MooseX::Getopt::Parser>
338
339=back
340
5dac17c3 341=head1 BUGS
342
4e086633 343All complex software has bugs lurking in it, and this module is no
5dac17c3 344exception. If you find a bug please either email me, or add the bug
345to cpan-RT.
346
347=head1 AUTHOR
348
349Stevan Little E<lt>stevan@iinteractive.comE<gt>
350
e2911e34 351Brandon L. Black, E<lt>blblack@gmail.comE<gt>
352
630657d5 353Yuval Kogman, E<lt>nothingmuch@woobling.orgE<gt>
354
78a71ae5 355=head1 CONTRIBUTORS
356
357Ryan D Johnson, E<lt>ryan@innerfence.comE<gt>
358
ac2073c8 359Piotr Roszatycki, E<lt>dexter@cpan.orgE<gt>
360
5dac17c3 361=head1 COPYRIGHT AND LICENSE
362
adbe3e57 363Copyright 2007-2008 by Infinity Interactive, Inc.
5dac17c3 364
365L<http://www.iinteractive.com>
366
367This library is free software; you can redistribute it and/or modify
368it under the same terms as Perl itself.
369
370=cut