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