support for recursive types, documentation and tests for that, random documentation...
[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.08;
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 RECURSIVE SUBTYPES
267
268 As of version 0.08, L<Moose::Types> has experimental support for Recursive
269 subtypes.  This will allow:
270
271     subtype Tree() => as HashRef[Str|Tree];
272
273 Which validates things like:
274
275     {key=>'value'};
276     {key=>{subkey1=>'value', subkey2=>'value'}}
277     
278 And so on.  This feature is new and there may be lurking bugs so don't be afraid
279 to hunt me down with patches and test cases if you have trouble.
280
281 =head1 NOTES REGARDING TYPE UNIONS
282
283 L<MooseX::Types> uses L<MooseX::Types::TypeDecorator> to do some overloading
284 which generally allows you to easily create union types:
285
286   subtype StrOrArrayRef,
287     as Str|ArrayRef;    
288
289 As with parameterized constrains, this overloading extends to modules using the
290 types you define in a type library.
291
292     use Moose;
293     use MooseX::Types::Moose qw(HashRef Int);
294     
295     has 'attr' => (isa=>HashRef|Int);
296
297 And everything should just work as you'd think.
298
299 =head1 METHODS
300
301 =head2 import
302
303 Installs the L<MooseX::Types::Base> class into the caller and 
304 exports types according to the specification described in 
305 L</"LIBRARY DEFINITION">. This will continue to 
306 L<Moose::Util::TypeConstraints>' C<import> method to export helper
307 functions you will need to declare your types.
308
309 =cut
310
311 sub import {
312     my ($class, %args) = @_;
313     my  $callee = caller;
314
315     # everyone should want this
316     strict->import;
317     warnings->import;
318
319     # inject base class into new library
320     {   no strict 'refs';
321         unshift @{ $callee . '::ISA' }, 'MooseX::Types::Base';
322     }
323
324     # generate predeclared type helpers
325     if (my @orig_declare = @{ $args{ -declare } || [] }) {
326         my ($tags, $declare) = filter_tags @orig_declare;
327         my @to_export;
328
329         for my $type (@$declare) {
330
331             croak "Cannot create a type containing '::' ($type) at the moment"
332                 if $type =~ /::/;
333
334             # add type to library and remember to export
335             $callee->add_type($type);
336             push @to_export, $type;
337         }
338
339         $callee->import({ -full => 1, -into => $callee }, @to_export);
340     }
341
342     # run type constraints import
343     return Moose::Util::TypeConstraints->import({ into => $callee });
344 }
345
346 =head2 type_export_generator
347
348 Generate a type export, e.g. C<Int()>. This will return either a
349 L<Moose::Meta::TypeConstraint> object, or alternatively a
350 L<MooseX::Types::UndefinedType> object if the type was not
351 yet defined.
352
353 =cut
354
355 sub type_export_generator {
356     my ($class, $type, $name) = @_;
357     
358     ## Return an anonymous subroutine that will generate the proxied type
359     ## constraint for you.
360     
361     return sub {
362         my $type_constraint;
363         if(defined(my $params = shift @_)) {
364             ## We currently only allow a TC to accept a single, ArrayRef
365             ## parameter, as in HashRef[Int], where [Int] is what's inside the
366             ## ArrayRef passed.
367             if(ref $params eq 'ARRAY') {
368                 $type_constraint = $class->create_arged_type_constraint($name, @$params);
369             } else {
370                 croak 'Arguments must be an ArrayRef, not '. ref $params;
371             }
372         } else {
373             $type_constraint = $class->create_base_type_constraint($name);
374         }
375
376         $type_constraint = defined($type_constraint) ? $type_constraint
377          : MooseX::Types::UndefinedType->new($name);
378          
379         my $type_decorator = $class->create_type_decorator($type_constraint);
380         
381         ## If there are additional args, that means it's probably stuff that
382         ## needs to be returned to the subtype.  Not an ideal solution here but
383         ## doesn't seem to cause trouble.
384         
385         if(@_) {
386             return ($type_decorator, @_);
387         } else {
388             return $type_decorator;
389         }
390     };
391 }
392
393 =head2 create_arged_type_constraint ($name, @args)
394
395 Given a String $name with @args find the matching typeconstraint and parameterize
396 it with @args.
397
398 =cut
399
400 sub create_arged_type_constraint {
401     my ($class, $name, @args) = @_;  
402     my $type_constraint = Moose::Util::TypeConstraints::find_or_create_type_constraint("$name");
403         return $type_constraint->parameterize(@args);
404 }
405
406 =head2 create_base_type_constraint ($name)
407
408 Given a String $name, find the matching typeconstraint.
409
410 =cut
411
412 sub create_base_type_constraint {
413     my ($class, $name) = @_;
414     return find_type_constraint($name);
415 }
416
417 =head2 create_type_decorator ($type_constraint)
418
419 Given a $type_constraint, return a lightweight L<MooseX::Types::TypeDecorator>
420 instance.
421
422 =cut
423
424 sub create_type_decorator {
425     my ($class, $type_constraint) = @_;
426     return MooseX::Types::TypeDecorator->new($type_constraint);
427 }
428
429 =head2 coercion_export_generator
430
431 This generates a coercion handler function, e.g. C<to_Int($value)>. 
432
433 =cut
434
435 sub coercion_export_generator {
436     my ($class, $type, $full, $undef_msg) = @_;
437     return sub {
438         my ($value) = @_;
439
440         # we need a type object
441         my $tobj = find_type_constraint($full) or croak $undef_msg;
442         my $return = $tobj->coerce($value);
443
444         # non-successful coercion returns false
445         return unless $tobj->check($return);
446
447         return $return;
448     }
449 }
450
451 =head2 check_export_generator
452
453 Generates a constraint check closure, e.g. C<is_Int($value)>.
454
455 =cut
456
457 sub check_export_generator {
458     my ($class, $type, $full, $undef_msg) = @_;
459     return sub {
460         my ($value) = @_;
461
462         # we need a type object
463         my $tobj = find_type_constraint($full) or croak $undef_msg;
464
465         return $tobj->check($value);
466     }
467 }
468
469 =head1 CAVEATS
470
471 The following are lists of gotcha's and their workarounds for developers coming
472 from the standard string based type constraint names
473
474 =head2 Uniqueness
475
476 A library makes the types quasi-unique by prefixing their names with (by
477 default) the library package name. If you're only using the type handler
478 functions provided by MooseX::Types, you shouldn't ever have to use
479 a type's actual full name.
480
481 =head2 Argument separation ('=>' versus ',')
482
483 The Perlop manpage has this to say about the '=>' operator: "The => operator is
484 a synonym for the comma, but forces any word (consisting entirely of word
485 characters) to its left to be interpreted as a string (as of 5.001). This
486 includes words that might otherwise be considered a constant or function call."
487
488 Due to this stringification, the following will NOT work as you might think:
489
490   subtype StrOrArrayRef => as Str|ArrayRef;
491   
492 The 'StrOrArrayRef' will have it's stringification activated this causes the
493 subtype to not be created.  Since the bareword type constraints are not strings
494 you really should not try to treat them that way.  You will have to use the ','
495 operator instead.  The author's of this package realize that all the L<Moose>
496 documention and examples nearly uniformly use the '=>' version of the comma
497 operator and this could be an issue if you are converting code.
498
499 Patches welcome for discussion.
500
501 =head2 Compatibility with Sub::Exporter
502
503 If you want to use L<Sub::Exporter> with a Type Library, you need to make sure
504 you export all the type constraints declared AS WELL AS any additional export
505 targets. For example if you do:
506
507     package TypeAndSubExporter; {
508         
509         use MooseX::Types::Moose qw(Str);
510         use MooseX::Types -declare => [qw(MyStr)];
511         use Sub::Exporter -setup => { exports => [ qw(something) ] };
512         
513         subtype MyStr,
514          as Str;
515          
516         sub something {
517             return 1;
518         }    
519         
520     } 1;
521     
522     package Foo; {
523         use TypeAndSubExporter qw(MyStr);
524     } 1;
525
526 You'll get a '"MyStr" is not exported by the TypeAndSubExporter module' error.
527 Upi can workaround by:
528
529         - use Sub::Exporter -setup => { exports => [ qw(something) ] };
530         + use Sub::Exporter -setup => { exports => [ qw(something MyStr) ] };
531
532 This is a workaround and I am exploring how to make these modules work better
533 together.  I realize this workaround will lead a lot of duplication in your
534 export declarations and will be onerous for large type libraries.  Patches and
535 detailed test cases welcome. See the tests directory for a start on this.
536     
537 =head1 SEE ALSO
538
539 L<Moose>, 
540 L<Moose::Util::TypeConstraints>, 
541 L<MooseX::Types::Moose>,
542 L<Sub::Exporter>
543
544 =head1 AUTHOR AND COPYRIGHT
545
546 Robert 'phaylon' Sedlacek C<E<lt>rs@474.atE<gt>>, with many thanks to
547 the C<#moose> cabal on C<irc.perl.org>.
548
549 Additional features by John Napiorkowski (jnapiorkowski) <jjnapiork@cpan.org>.
550
551 =head1 LICENSE
552
553 This program is free software; you can redistribute it and/or modify
554 it under the same terms as perl itself.
555
556 =cut
557
558 1;