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