spelling and pod fixes
[gitmo/MooseX-Types.git] / lib / MooseX / Types.pm
CommitLineData
52d358e2 1package MooseX::Types;
16ddefbf 2use Moose;
8af0a70d 3
ef8b7b7a 4# ABSTRACT: Organise your Moose types in libraries
8af0a70d 5
8af0a70d 6use Moose::Util::TypeConstraints;
4c2125a4 7use MooseX::Types::TypeDecorator;
b0db42a9 8use MooseX::Types::Base ();
9use MooseX::Types::Util qw( filter_tags );
52d358e2 10use MooseX::Types::UndefinedType;
b0db42a9 11use MooseX::Types::CheckedUtilExports ();
12use Carp::Clan qw( ^MooseX::Types );
13use Sub::Name;
14use Scalar::Util 'reftype';
9616cebc 15
4eb26e95 16use namespace::autoclean;
8af0a70d 17
eba48805 18use 5.008;
8af0a70d 19my $UndefMsg = q{Action for type '%s' not yet defined in library '%s'};
20
8bf27efd 21=pod
22
8af0a70d 23=head1 SYNOPSIS
24
9616cebc 25=head2 Library Definition
26
8af0a70d 27 package MyLibrary;
8af0a70d 28
29 # predeclare our own types
7b880bf1 30 use MooseX::Types -declare => [
31 qw(
32 PositiveInt
33 NegativeInt
34 ArrayRefOfPositiveInt
35 ArrayRefOfAtLeastThreeNegativeInts
36 LotsOfInnerConstraints
37 StrOrArrayRef
38 MyDateTime
39 )
40 ];
8af0a70d 41
42 # import builtin types
b0db42a9 43 use MooseX::Types::Moose qw/Int HashRef/;
8af0a70d 44
77134b88 45 # type definition.
7b880bf1 46 subtype PositiveInt,
47 as Int,
8af0a70d 48 where { $_ > 0 },
49 message { "Int is not larger than 0" };
7b880bf1 50
8af0a70d 51 subtype NegativeInt,
52 as Int,
53 where { $_ < 0 },
54 message { "Int is not smaller than 0" };
55
56 # type coercion
57 coerce PositiveInt,
58 from Int,
59 via { 1 };
60
d9002a85 61 # with parameterized constraints.
7b880bf1 62
475bbd1d 63 subtype ArrayRefOfPositiveInt,
d9002a85 64 as ArrayRef[PositiveInt];
7b880bf1 65
475bbd1d 66 subtype ArrayRefOfAtLeastThreeNegativeInts,
d9002a85 67 as ArrayRef[NegativeInt],
475bbd1d 68 where { scalar(@$_) > 2 };
69
70 subtype LotsOfInnerConstraints,
d9002a85 71 as ArrayRef[ArrayRef[HashRef[Int]]];
7b880bf1 72
475bbd1d 73 # with TypeConstraint Unions
7b880bf1 74
475bbd1d 75 subtype StrOrArrayRef,
76 as Str|ArrayRef;
77
6cfbfdbc 78 # class types
79
b0db42a9 80 class_type 'DateTime';
81
6cfbfdbc 82 # or better
83
84 class_type MyDateTime, { class => 'DateTime' };
85
86 coerce MyDateTime,
b0db42a9 87 from HashRef,
88 via { DateTime->new(%$_) };
89
8af0a70d 90 1;
91
9616cebc 92=head2 Usage
93
8af0a70d 94 package Foo;
95 use Moose;
96 use MyLibrary qw( PositiveInt NegativeInt );
97
98 # use the exported constants as type names
99 has 'bar',
100 isa => PositiveInt,
101 is => 'rw';
102 has 'baz',
103 isa => NegativeInt,
104 is => 'rw';
105
106 sub quux {
107 my ($self, $value);
108
109 # test the value
110 print "positive\n" if is_PositiveInt($value);
111 print "negative\n" if is_NegativeInt($value);
112
113 # coerce the value, NegativeInt doesn't have a coercion
114 # helper, since it didn't define any coercions.
115 $value = to_PositiveInt($value) or die "Cannot coerce";
116 }
117
118 1;
119
120=head1 DESCRIPTION
121
93f28db7 122The type system provided by Moose effectively makes all of its builtin type
123global, as are any types you declare with Moose. This means that every module
8bf27efd 124that declares a type named C<PositiveInt> is sharing the same type object. This
93f28db7 125can be a problem when different parts of the code base want to use the same
126name for different things.
8af0a70d 127
93f28db7 128This package lets you declare types using short names, but behind the scenes
129it namespaces all your type declarations, effectively prevent name clashes
130between packages.
8af0a70d 131
93f28db7 132This is done by creating a type library module like C<MyApp::Types> and then
133importing types from that module into other modules.
8af0a70d 134
93f28db7 135As a side effect, the declaration mechanism allows you to write type names as
136barewords (really function calls), which catches typos in names at compile
137time rather than run time.
b0db42a9 138
93f28db7 139This module also provides some helper functions for using Moose types outside
140of attribute declarations.
8af0a70d 141
93f28db7 142If you mix string-based names with types created by this module, it will warn,
143with a few exceptions. If you are declaring a C<class_type()> or
e5c925c6 144C<role_type()> within your type library, or if you use a fully qualified name
93f28db7 145like C<"MyApp::Foo">.
8af0a70d 146
147=head1 LIBRARY DEFINITION
148
e9dc30af 149A MooseX::Types is just a normal Perl module. Unlike Moose
8af0a70d 150itself, it does not install C<use strict> and C<use warnings> in your
151class by default, so this is up to you.
152
153The only thing a library is required to do is
154
52d358e2 155 use MooseX::Types -declare => \@types;
8af0a70d 156
157with C<@types> being a list of types you wish to define in this library.
158This line will install a proper base class in your package as well as the
e9dc30af 159full set of L<handlers|/"TYPE HANDLER FUNCTIONS"> for your declared
8af0a70d 160types. It will then hand control over to L<Moose::Util::TypeConstraints>'
161C<import> method to export the functions you will need to declare your
162types.
163
e9dc30af 164If you want to use Moose' built-in types (e.g. for subtyping) you will
165want to
8af0a70d 166
52d358e2 167 use MooseX::Types::Moose @types;
8af0a70d 168
52d358e2 169to import the helpers from the shipped L<MooseX::Types::Moose>
8af0a70d 170library which can export all types that come with Moose.
171
172You will have to define coercions for your types or your library won't
173export a L</to_$type> coercion helper for it.
174
e9dc30af 175Note that you currently cannot define types containing C<::>, since
249888e7 176exporting would be a problem.
177
559cf3d8 178You also don't need to use C<warnings> and C<strict>, since the
179definition of a library automatically exports those.
180
8af0a70d 181=head1 LIBRARY USAGE
182
183You can import the L<"type helpers"|/"TYPE HANDLER FUNCTIONS"> of a
184library by C<use>ing it with a list of types to import as arguments. If
185you want all of them, use the C<:all> tag. For example:
186
187 use MyLibrary ':all';
188 use MyOtherLibrary qw( TypeA TypeB );
189
52d358e2 190MooseX::Types comes with a library of Moose' built-in types called
191L<MooseX::Types::Moose>.
8af0a70d 192
16ddefbf 193The exporting mechanism is, since version 0.5, implemented via a wrapper
194around L<Sub::Exporter>. This means you can do something like this:
195
196 use MyLibrary TypeA => { -as => 'MyTypeA' },
197 TypeB => { -as => 'MyTypeB' };
198
93f28db7 199=head1 TYPE HANDLER FUNCTIONS
200
201=head2 $type
202
203A constant with the name of your type. It contains the type's fully
204qualified name. Takes no value, as all constants.
205
206=head2 is_$type
207
208This handler takes a value and tests if it is a valid value for this
209C<$type>. It will return true or false.
210
211=head2 to_$type
212
213A handler that will take a value and coerce it into the C<$type>. It will
214return a false value if the type could not be coerced.
215
216B<Important Note>: This handler will only be exported for types that can
217do type coercion. This has the advantage that a coercion to a type that
218has not defined any coercions will lead to a compile-time error.
219
c20dc98b 220=head1 WRAPPING A LIBRARY
221
222You can define your own wrapper subclasses to manipulate the behaviour
223of a set of library exports. Here is an example:
224
225 package MyWrapper;
226 use strict;
df773753 227 use MRO::Compat;
52d358e2 228 use base 'MooseX::Types::Wrapper';
c20dc98b 229
230 sub coercion_export_generator {
231 my $class = shift;
232 my $code = $class->next::method(@_);
233 return sub {
234 my $value = $code->(@_);
235 warn "Coercion returned undef!"
236 unless defined $value;
237 return $value;
238 };
239 }
240
241 1;
242
243This class wraps the coercion generator (e.g., C<to_Int()>) and warns
244if a coercion returned an undefined value. You can wrap any library
245with this:
246
247 package Foo;
248 use strict;
249 use MyWrapper MyLibrary => [qw( Foo Bar )],
250 Moose => [qw( Str Int )];
251
252 ...
253 1;
254
93f28db7 255The C<Moose> library name is a special shortcut for L<MooseX::Types::Moose>.
c20dc98b 256
257=head2 Generator methods you can overload
258
259=over 4
260
261=item type_export_generator( $short, $full )
262
93f28db7 263Creates a closure returning the type's L<Moose::Meta::TypeConstraint> object.
c20dc98b 264
265=item check_export_generator( $short, $full, $undef_message )
266
267This creates the closure used to test if a value is valid for this type.
268
269=item coercion_export_generator( $short, $full, $undef_message )
270
271This is the closure that's doing coercions.
272
273=back
274
275=head2 Provided Parameters
276
277=over 4
278
279=item $short
280
281The short, exported name of the type.
282
283=item $full
284
285The fully qualified name of this type as L<Moose> knows it.
286
287=item $undef_message
288
289A message that will be thrown when type functionality is used but the
290type does not yet exist.
291
0ad3779e 292=back
293
077ac262 294=head1 RECURSIVE SUBTYPES
295
296As of version 0.08, L<Moose::Types> has experimental support for Recursive
297subtypes. This will allow:
298
299 subtype Tree() => as HashRef[Str|Tree];
300
301Which validates things like:
302
303 {key=>'value'};
304 {key=>{subkey1=>'value', subkey2=>'value'}}
93f28db7 305
077ac262 306And so on. This feature is new and there may be lurking bugs so don't be afraid
307to hunt me down with patches and test cases if you have trouble.
308
475bbd1d 309=head1 NOTES REGARDING TYPE UNIONS
310
311L<MooseX::Types> uses L<MooseX::Types::TypeDecorator> to do some overloading
312which generally allows you to easily create union types:
313
314 subtype StrOrArrayRef,
93f28db7 315 as Str|ArrayRef;
475bbd1d 316
bac4f72c 317As with parameterized constraints, this overloading extends to modules using the
475bbd1d 318types you define in a type library.
319
93f28db7 320 use Moose;
321 use MooseX::Types::Moose qw(HashRef Int);
322
323 has 'attr' => ( isa => HashRef | Int );
475bbd1d 324
325And everything should just work as you'd think.
77134b88 326
8af0a70d 327=head1 METHODS
328
329=head2 import
330
93f28db7 331Installs the L<MooseX::Types::Base> class into the caller and exports types
332according to the specification described in L</"LIBRARY DEFINITION">. This
333will continue to L<Moose::Util::TypeConstraints>' C<import> method to export
334helper functions you will need to declare your types.
e211870f 335
8af0a70d 336=cut
337
338sub import {
339 my ($class, %args) = @_;
5c3e47c7 340 my $caller = caller;
8af0a70d 341
559cf3d8 342 # everyone should want this
343 strict->import;
344 warnings->import;
345
8af0a70d 346 # inject base class into new library
347 { no strict 'refs';
5c3e47c7 348 unshift @{ $caller . '::ISA' }, 'MooseX::Types::Base';
8af0a70d 349 }
350
351 # generate predeclared type helpers
e211870f 352 if (my @orig_declare = @{ $args{ -declare } || [] }) {
353 my ($tags, $declare) = filter_tags @orig_declare;
16ddefbf 354 my @to_export;
e211870f 355
356 for my $type (@$declare) {
249888e7 357
358 croak "Cannot create a type containing '::' ($type) at the moment"
359 if $type =~ /::/;
360
16ddefbf 361 # add type to library and remember to export
5c3e47c7 362 $caller->add_type($type);
16ddefbf 363 push @to_export, $type;
8af0a70d 364 }
16ddefbf 365
5c3e47c7 366 $caller->import({ -full => 1, -into => $caller }, @to_export);
8af0a70d 367 }
368
369 # run type constraints import
5c3e47c7 370 Moose::Util::TypeConstraints->import({ into => $caller });
b0db42a9 371
372 # override some with versions that check for syntax errors
5c3e47c7 373 MooseX::Types::CheckedUtilExports->import({ into => $caller });
b0db42a9 374
375 1;
8af0a70d 376}
377
378=head2 type_export_generator
379
e211870f 380Generate a type export, e.g. C<Int()>. This will return either a
381L<Moose::Meta::TypeConstraint> object, or alternatively a
93f28db7 382L<MooseX::Types::UndefinedType> object if the type was not yet defined.
e211870f 383
8af0a70d 384=cut
385
386sub type_export_generator {
a706b0f2 387 my ($class, $type, $name) = @_;
e9dc30af 388
686e5888 389 ## Return an anonymous subroutine that will generate the proxied type
390 ## constraint for you.
4e6dc81d 391
1150ce72 392 return subname "__TYPE__::$name" => sub {
b0db42a9 393 my $type_constraint = $class->create_base_type_constraint($name);
394
e088dd03 395 if(defined(my $params = shift @_)) {
686e5888 396 ## We currently only allow a TC to accept a single, ArrayRef
397 ## parameter, as in HashRef[Int], where [Int] is what's inside the
398 ## ArrayRef passed.
b0db42a9 399 if(reftype $params eq 'ARRAY') {
e088dd03 400 $type_constraint = $class->create_arged_type_constraint($name, @$params);
b0db42a9 401 } elsif(!defined $type_constraint) {
402 croak "Syntax error in type definition (did you forget a comma"
403 . " after $type?)";
e088dd03 404 } else {
b0db42a9 405 croak "Argument must be an ArrayRef to create a parameterized "
406 . "type, Eg.: ${type}[Int]. Got: ".ref($params)."."
e088dd03 407 }
e088dd03 408 }
e7d06577 409
e088dd03 410 $type_constraint = defined($type_constraint) ? $type_constraint
411 : MooseX::Types::UndefinedType->new($name);
e9dc30af 412
d9002a85 413 my $type_decorator = $class->create_type_decorator($type_constraint);
e9dc30af 414
686e5888 415 ## If there are additional args, that means it's probably stuff that
416 ## needs to be returned to the subtype. Not an ideal solution here but
417 ## doesn't seem to cause trouble.
e9dc30af 418
d9002a85 419 if(@_) {
420 return ($type_decorator, @_);
421 } else {
422 return $type_decorator;
423 }
e211870f 424 };
8af0a70d 425}
426
a706b0f2 427=head2 create_arged_type_constraint ($name, @args)
428
8bf27efd 429Given a String $name with @args find the matching type constraint and parameterize
686e5888 430it with @args.
a706b0f2 431
432=cut
433
434sub create_arged_type_constraint {
e9dc30af 435 my ($class, $name, @args) = @_;
371efa05 436 my $type_constraint = Moose::Util::TypeConstraints::find_or_create_type_constraint("$name");
8a58233c 437 my $parameterized = $type_constraint->parameterize(@args);
438 # It's obnoxious to have to parameterize before looking for the TC, but the
439 # alternative is to hard-code the assumption that the name is
440 # "$name[$args[0]]", which would be worse.
64f42303 441 # This breaks MXMS, unfortunately, which relies on things like Tuple[...]
442 # creating new type objects each time.
443 # if (my $existing =
444 # Moose::Util::TypeConstraints::find_type_constraint($parameterized->name)) {
445 # return $existing;
446 # }
447 # Moose::Util::TypeConstraints::register_type_constraint($parameterized);
8a58233c 448 return $parameterized;
a706b0f2 449}
450
451=head2 create_base_type_constraint ($name)
452
93f28db7 453Given a String $name, find the matching type constraint.
a706b0f2 454
455=cut
456
457sub create_base_type_constraint {
458 my ($class, $name) = @_;
459 return find_type_constraint($name);
460}
461
462=head2 create_type_decorator ($type_constraint)
463
464Given a $type_constraint, return a lightweight L<MooseX::Types::TypeDecorator>
465instance.
466
467=cut
468
469sub create_type_decorator {
470 my ($class, $type_constraint) = @_;
475bbd1d 471 return MooseX::Types::TypeDecorator->new($type_constraint);
a706b0f2 472}
473
8af0a70d 474=head2 coercion_export_generator
475
93f28db7 476This generates a coercion handler function, e.g. C<to_Int($value)>.
e211870f 477
8af0a70d 478=cut
479
480sub coercion_export_generator {
481 my ($class, $type, $full, $undef_msg) = @_;
482 return sub {
483 my ($value) = @_;
484
485 # we need a type object
486 my $tobj = find_type_constraint($full) or croak $undef_msg;
487 my $return = $tobj->coerce($value);
488
489 # non-successful coercion returns false
490 return unless $tobj->check($return);
491
492 return $return;
493 }
494}
495
496=head2 check_export_generator
497
e211870f 498Generates a constraint check closure, e.g. C<is_Int($value)>.
499
8af0a70d 500=cut
501
502sub check_export_generator {
503 my ($class, $type, $full, $undef_msg) = @_;
504 return sub {
505 my ($value) = @_;
506
507 # we need a type object
508 my $tobj = find_type_constraint($full) or croak $undef_msg;
509
510 return $tobj->check($value);
511 }
512}
513
e211870f 514=head1 CAVEATS
515
93f28db7 516The following are lists of gotchas and their workarounds for developers coming
686e5888 517from the standard string based type constraint names
518
519=head2 Uniqueness
520
e211870f 521A library makes the types quasi-unique by prefixing their names with (by
522default) the library package name. If you're only using the type handler
52d358e2 523functions provided by MooseX::Types, you shouldn't ever have to use
e211870f 524a type's actual full name.
525
686e5888 526=head2 Argument separation ('=>' versus ',')
527
93f28db7 528The L<perlop> manpage has this to say about the '=>' operator: "The => operator is
686e5888 529a synonym for the comma, but forces any word (consisting entirely of word
530characters) to its left to be interpreted as a string (as of 5.001). This
531includes words that might otherwise be considered a constant or function call."
532
533Due to this stringification, the following will NOT work as you might think:
534
93f28db7 535 subtype StrOrArrayRef => as Str | ArrayRef;
536
8bf27efd 537The C<StrOrArrayRef> type will have its stringification activated -- this causes the
686e5888 538subtype to not be created. Since the bareword type constraints are not strings
539you really should not try to treat them that way. You will have to use the ','
16b11399 540operator instead. The authors of this package realize that all the L<Moose>
c807eb83 541documentation and examples nearly uniformly use the '=>' version of the comma
686e5888 542operator and this could be an issue if you are converting code.
543
544Patches welcome for discussion.
077ac262 545
546=head2 Compatibility with Sub::Exporter
547
548If you want to use L<Sub::Exporter> with a Type Library, you need to make sure
549you export all the type constraints declared AS WELL AS any additional export
550targets. For example if you do:
551
93f28db7 552 package TypeAndSubExporter;
553
554 use MooseX::Types::Moose qw(Str);
555 use MooseX::Types -declare => [qw(MyStr)];
556 use Sub::Exporter -setup => { exports => [qw(something)] };
557
558 subtype MyStr, as Str;
559
560 sub something {
561 return 1;
562 }
563
564 # then in another module ...
565
566 package Foo;
567 use TypeAndSubExporter qw(MyStr);
077ac262 568
8bf27efd 569You'll get a C<< "MyStr" is not exported by the TypeAndSubExporter module >> error.
47464996 570It can be worked around by:
077ac262 571
93f28db7 572 - use Sub::Exporter -setup => { exports => [ qw(something) ] };
573 + use Sub::Exporter -setup => { exports => [ qw(something MyStr) ] };
077ac262 574
575This is a workaround and I am exploring how to make these modules work better
576together. I realize this workaround will lead a lot of duplication in your
577export declarations and will be onerous for large type libraries. Patches and
578detailed test cases welcome. See the tests directory for a start on this.
29dcd6ad 579
580=head1 COMBINING TYPE LIBRARIES
581
582You may want to combine a set of types for your application with other type
583libraries, like L<MooseX::Types::Moose> or L<MooseX::Types::Common::String>.
584
585The L<MooseX::Types::Combine> module provides a simple API for combining a set
586of type libraries together.
587
8af0a70d 588=head1 SEE ALSO
589
93f28db7 590L<Moose>, L<Moose::Util::TypeConstraints>, L<MooseX::Types::Moose>,
16ddefbf 591L<Sub::Exporter>
8af0a70d 592
b55332a8 593=head1 ACKNOWLEDGEMENTS
8af0a70d 594
b55332a8 595Many thanks to the C<#moose> cabal on C<irc.perl.org>.
8af0a70d 596
8af0a70d 597=cut