added minimum Perl version
[gitmo/MooseX-Types.git] / lib / MooseX / Types.pm
1 package MooseX::Types;
2 use Moose;
3
4 =head1 NAME
5
6 MooseX::Types - Organise your Moose types in libraries
7
8 =cut
9
10 #use warnings;
11 #use strict;
12
13 use Moose::Util::TypeConstraints;
14 use MooseX::Types::TypeDecorator;
15 use MooseX::Types::Base             ();
16 use MooseX::Types::Util             qw( filter_tags );
17 use MooseX::Types::UndefinedType;
18 use Carp::Clan                      qw( ^MooseX::Types );
19
20 use namespace::clean -except => [qw( meta )];
21
22 use 5.008;
23 our $VERSION = 0.07;
24 my $UndefMsg = q{Action for type '%s' not yet defined in library '%s'};
25
26 =head1 SYNOPSIS
27
28 =head2 Library Definition
29
30   package MyLibrary;
31
32   # predeclare our own types
33   use MooseX::Types 
34     -declare => [qw(
35         PositiveInt NegativeInt
36         ArrayRefOfPositiveInt ArrayRefOfAtLeastThreeNegativeInts
37         LotsOfInnerConstraints StrOrArrayRef
38     )];
39
40   # import builtin types
41   use MooseX::Types::Moose 'Int';
42
43   # type definition.
44   subtype PositiveInt, 
45       as Int, 
46       where { $_ > 0 },
47       message { "Int is not larger than 0" };
48   
49   subtype NegativeInt,
50       as Int,
51       where { $_ < 0 },
52       message { "Int is not smaller than 0" };
53
54   # type coercion
55   coerce PositiveInt,
56       from Int,
57           via { 1 };
58
59   # with parameterized constraints.
60   
61   subtype ArrayRefOfPositiveInt,
62     as ArrayRef[PositiveInt];
63     
64   subtype ArrayRefOfAtLeastThreeNegativeInts,
65     as ArrayRef[NegativeInt],
66     where { scalar(@$_) > 2 };
67
68   subtype LotsOfInnerConstraints,
69     as ArrayRef[ArrayRef[HashRef[Int]]];
70     
71   # with TypeConstraint Unions
72   
73   subtype StrOrArrayRef,
74     as Str|ArrayRef;
75
76   1;
77
78 =head2 Usage
79
80   package Foo;
81   use Moose;
82   use MyLibrary qw( PositiveInt NegativeInt );
83
84   # use the exported constants as type names
85   has 'bar',
86       isa    => PositiveInt,
87       is     => 'rw';
88   has 'baz',
89       isa    => NegativeInt,
90       is     => 'rw';
91
92   sub quux {
93       my ($self, $value);
94
95       # test the value
96       print "positive\n" if is_PositiveInt($value);
97       print "negative\n" if is_NegativeInt($value);
98
99       # coerce the value, NegativeInt doesn't have a coercion
100       # helper, since it didn't define any coercions.
101       $value = to_PositiveInt($value) or die "Cannot coerce";
102   }
103
104   1;
105
106 =head1 DESCRIPTION
107
108 The types provided with L<Moose> are by design global. This package helps
109 you to organise and selectively import your own and the built-in types in
110 libraries. As a nice side effect, it catches typos at compile-time too.
111
112 However, the main reason for this module is to provide an easy way to not
113 have conflicts with your type names, since the internal fully qualified
114 names of the types will be prefixed with the library's name.
115
116 This module will also provide you with some helper functions to make it 
117 easier to use Moose types in your code.
118
119 =head1 TYPE HANDLER FUNCTIONS
120
121 =head2 $type
122
123 A constant with the name of your type. It contains the type's fully
124 qualified name. Takes no value, as all constants.
125
126 =head2 is_$type
127
128 This handler takes a value and tests if it is a valid value for this
129 C<$type>. It will return true or false.
130
131 =head2 to_$type
132
133 A handler that will take a value and coerce it into the C<$type>. It will
134 return a false value if the type could not be coerced.
135
136 B<Important Note>: This handler will only be exported for types that can
137 do type coercion. This has the advantage that a coercion to a type that
138 cannot hasn't defined any coercions will lead to a compile-time error.
139
140 =head1 LIBRARY DEFINITION
141
142 A MooseX::Types is just a normal Perl module. Unlike Moose 
143 itself, it does not install C<use strict> and C<use warnings> in your
144 class by default, so this is up to you.
145
146 The only thing a library is required to do is
147
148   use MooseX::Types -declare => \@types;
149
150 with C<@types> being a list of types you wish to define in this library.
151 This line will install a proper base class in your package as well as the
152 full set of L<handlers|/"TYPE HANDLER FUNCTIONS"> for your declared 
153 types. It will then hand control over to L<Moose::Util::TypeConstraints>'
154 C<import> method to export the functions you will need to declare your
155 types.
156
157 If you want to use Moose' built-in types (e.g. for subtyping) you will 
158 want to 
159
160   use MooseX::Types::Moose @types;
161
162 to import the helpers from the shipped L<MooseX::Types::Moose>
163 library which can export all types that come with Moose.
164
165 You will have to define coercions for your types or your library won't
166 export a L</to_$type> coercion helper for it.
167
168 Note that you currently cannot define types containing C<::>, since 
169 exporting would be a problem.
170
171 You also don't need to use C<warnings> and C<strict>, since the
172 definition of a library automatically exports those.
173
174 =head1 LIBRARY USAGE
175
176 You can import the L<"type helpers"|/"TYPE HANDLER FUNCTIONS"> of a
177 library by C<use>ing it with a list of types to import as arguments. If
178 you want all of them, use the C<:all> tag. For example:
179
180   use MyLibrary      ':all';
181   use MyOtherLibrary qw( TypeA TypeB );
182
183 MooseX::Types comes with a library of Moose' built-in types called
184 L<MooseX::Types::Moose>.
185
186 The exporting mechanism is, since version 0.5, implemented via a wrapper
187 around L<Sub::Exporter>. This means you can do something like this:
188
189   use MyLibrary TypeA => { -as => 'MyTypeA' },
190                 TypeB => { -as => 'MyTypeB' };
191
192 =head1 WRAPPING A LIBRARY
193
194 You can define your own wrapper subclasses to manipulate the behaviour
195 of a set of library exports. Here is an example:
196
197   package MyWrapper;
198   use strict;
199   use Class::C3;
200   use base 'MooseX::Types::Wrapper';
201
202   sub coercion_export_generator {
203       my $class = shift;
204       my $code = $class->next::method(@_);
205       return sub {
206           my $value = $code->(@_);
207           warn "Coercion returned undef!"
208               unless defined $value;
209           return $value;
210       };
211   }
212
213   1;
214
215 This class wraps the coercion generator (e.g., C<to_Int()>) and warns
216 if a coercion returned an undefined value. You can wrap any library
217 with this:
218
219   package Foo;
220   use strict;
221   use MyWrapper MyLibrary => [qw( Foo Bar )],
222                 Moose     => [qw( Str Int )];
223
224   ...
225   1;
226
227 The C<Moose> library name is a special shortcut for 
228 L<MooseX::Types::Moose>.
229
230 =head2 Generator methods you can overload
231
232 =over 4
233
234 =item type_export_generator( $short, $full )
235
236 Creates a closure returning the type's L<Moose::Meta::TypeConstraint> 
237 object. 
238
239 =item check_export_generator( $short, $full, $undef_message )
240
241 This creates the closure used to test if a value is valid for this type.
242
243 =item coercion_export_generator( $short, $full, $undef_message )
244
245 This is the closure that's doing coercions.
246
247 =back
248
249 =head2 Provided Parameters
250
251 =over 4
252
253 =item $short
254
255 The short, exported name of the type.
256
257 =item $full
258
259 The fully qualified name of this type as L<Moose> knows it.
260
261 =item $undef_message
262
263 A message that will be thrown when type functionality is used but the
264 type does not yet exist.
265
266 =head1 NOTES REGARDING TYPE UNIONS
267
268 L<MooseX::Types> uses L<MooseX::Types::TypeDecorator> to do some overloading
269 which generally allows you to easily create union types:
270
271   subtype StrOrArrayRef,
272     as Str|ArrayRef;    
273
274 As with parameterized constrains, this overloading extends to modules using the
275 types you define in a type library.
276
277     use Moose;
278     use MooseX::Types::Moose qw(HashRef Int);
279     
280     has 'attr' => (isa=>HashRef|Int);
281
282 And everything should just work as you'd think.
283
284 =head1 METHODS
285
286 =head2 import
287
288 Installs the L<MooseX::Types::Base> class into the caller and 
289 exports types according to the specification described in 
290 L</"LIBRARY DEFINITION">. This will continue to 
291 L<Moose::Util::TypeConstraints>' C<import> method to export helper
292 functions you will need to declare your types.
293
294 =cut
295
296 sub import {
297     my ($class, %args) = @_;
298     my  $callee = caller;
299
300     # everyone should want this
301     strict->import;
302     warnings->import;
303
304     # inject base class into new library
305     {   no strict 'refs';
306         unshift @{ $callee . '::ISA' }, 'MooseX::Types::Base';
307     }
308
309     # generate predeclared type helpers
310     if (my @orig_declare = @{ $args{ -declare } || [] }) {
311         my ($tags, $declare) = filter_tags @orig_declare;
312         my @to_export;
313
314         for my $type (@$declare) {
315
316             croak "Cannot create a type containing '::' ($type) at the moment"
317                 if $type =~ /::/;
318
319             # add type to library and remember to export
320             $callee->add_type($type);
321             push @to_export, $type;
322         }
323
324         $callee->import({ -full => 1, -into => $callee }, @to_export);
325     }
326
327     # run type constraints import
328     return Moose::Util::TypeConstraints->import({ into => $callee });
329 }
330
331 =head2 type_export_generator
332
333 Generate a type export, e.g. C<Int()>. This will return either a
334 L<Moose::Meta::TypeConstraint> object, or alternatively a
335 L<MooseX::Types::UndefinedType> object if the type was not
336 yet defined.
337
338 =cut
339
340 sub type_export_generator {
341     my ($class, $type, $name) = @_;
342     
343     ## Return an anonymous subroutine that will generate the proxied type
344     ## constraint for you.
345     
346     return sub {
347         my $type_constraint;
348         if(defined(my $params = shift @_)) {
349             ## We currently only allow a TC to accept a single, ArrayRef
350             ## parameter, as in HashRef[Int], where [Int] is what's inside the
351             ## ArrayRef passed.
352             if(ref $params eq 'ARRAY') {
353                 $type_constraint = $class->create_arged_type_constraint($name, @$params);
354             } else {
355                 croak 'Arguments must be an ArrayRef, not '. ref $params;
356             }
357         } else {
358             $type_constraint = $class->create_base_type_constraint($name);
359         }
360         $type_constraint = defined($type_constraint) ? $type_constraint
361          : MooseX::Types::UndefinedType->new($name);
362          
363         my $type_decorator = $class->create_type_decorator($type_constraint);
364         
365         ## If there are additional args, that means it's probably stuff that
366         ## needs to be returned to the subtype.  Not an ideal solution here but
367         ## doesn't seem to cause trouble.
368         
369         if(@_) {
370             return ($type_decorator, @_);
371         } else {
372             return $type_decorator;
373         }
374     };
375 }
376
377 =head2 create_arged_type_constraint ($name, @args)
378
379 Given a String $name with @args find the matching typeconstraint and parameterize
380 it with @args.
381
382 =cut
383
384 sub create_arged_type_constraint {
385     my ($class, $name, @args) = @_;  
386     my $type_constraint = Moose::Util::TypeConstraints::find_or_create_type_constraint("$name");
387         return $type_constraint->parameterize(@args);
388 }
389
390 =head2 create_base_type_constraint ($name)
391
392 Given a String $name, find the matching typeconstraint.
393
394 =cut
395
396 sub create_base_type_constraint {
397     my ($class, $name) = @_;
398     return find_type_constraint($name);
399 }
400
401 =head2 create_type_decorator ($type_constraint)
402
403 Given a $type_constraint, return a lightweight L<MooseX::Types::TypeDecorator>
404 instance.
405
406 =cut
407
408 sub create_type_decorator {
409     my ($class, $type_constraint) = @_;
410     return MooseX::Types::TypeDecorator->new($type_constraint);
411 }
412
413 =head2 coercion_export_generator
414
415 This generates a coercion handler function, e.g. C<to_Int($value)>. 
416
417 =cut
418
419 sub coercion_export_generator {
420     my ($class, $type, $full, $undef_msg) = @_;
421     return sub {
422         my ($value) = @_;
423
424         # we need a type object
425         my $tobj = find_type_constraint($full) or croak $undef_msg;
426         my $return = $tobj->coerce($value);
427
428         # non-successful coercion returns false
429         return unless $tobj->check($return);
430
431         return $return;
432     }
433 }
434
435 =head2 check_export_generator
436
437 Generates a constraint check closure, e.g. C<is_Int($value)>.
438
439 =cut
440
441 sub check_export_generator {
442     my ($class, $type, $full, $undef_msg) = @_;
443     return sub {
444         my ($value) = @_;
445
446         # we need a type object
447         my $tobj = find_type_constraint($full) or croak $undef_msg;
448
449         return $tobj->check($value);
450     }
451 }
452
453 =head1 CAVEATS
454
455 The following are lists of gotcha's and their workarounds for developers coming
456 from the standard string based type constraint names
457
458 =head2 Uniqueness
459
460 A library makes the types quasi-unique by prefixing their names with (by
461 default) the library package name. If you're only using the type handler
462 functions provided by MooseX::Types, you shouldn't ever have to use
463 a type's actual full name.
464
465 =head2 Argument separation ('=>' versus ',')
466
467 The Perlop manpage has this to say about the '=>' operator: "The => operator is
468 a synonym for the comma, but forces any word (consisting entirely of word
469 characters) to its left to be interpreted as a string (as of 5.001). This
470 includes words that might otherwise be considered a constant or function call."
471
472 Due to this stringification, the following will NOT work as you might think:
473
474   subtype StrOrArrayRef => as Str|ArrayRef;
475   
476 The 'StrOrArrayRef' will have it's stringification activated this causes the
477 subtype to not be created.  Since the bareword type constraints are not strings
478 you really should not try to treat them that way.  You will have to use the ','
479 operator instead.  The author's of this package realize that all the L<Moose>
480 documention and examples nearly uniformly use the '=>' version of the comma
481 operator and this could be an issue if you are converting code.
482
483 Patches welcome for discussion.
484     
485 =head1 SEE ALSO
486
487 L<Moose>, 
488 L<Moose::Util::TypeConstraints>, 
489 L<MooseX::Types::Moose>,
490 L<Sub::Exporter>
491
492 =head1 AUTHOR AND COPYRIGHT
493
494 Robert 'phaylon' Sedlacek C<E<lt>rs@474.atE<gt>>, with many thanks to
495 the C<#moose> cabal on C<irc.perl.org>.
496
497 Additional features by John Napiorkowski (jnapiorkowski) <jjnapiork@cpan.org>.
498
499 =head1 LICENSE
500
501 This program is free software; you can redistribute it and/or modify
502 it under the same terms as perl itself.
503
504 =cut
505
506 1;