2d6a438bd3256c48e8670a6d6d104be41b3cb83a
[gitmo/Moose.git] / lib / Moose / Util / TypeConstraints.pm
1
2 package Moose::Util::TypeConstraints;
3
4 use strict;
5 use warnings;
6
7 use Carp         'confess';
8 use Scalar::Util 'blessed', 'reftype';
9 use Sub::Exporter;
10
11 our $VERSION   = '0.19';
12 our $AUTHORITY = 'cpan:STEVAN';
13
14 ## --------------------------------------------------------
15 # Prototyped subs must be predeclared because we have a
16 # circular dependency with Moose::Meta::Attribute et. al.
17 # so in case of us being use'd first the predeclaration
18 # ensures the prototypes are in scope when consumers are
19 # compiled.
20
21 # creation and location
22 sub find_type_constraint                 ($);
23 sub register_type_constraint             ($);
24 sub find_or_create_type_constraint       ($;$);
25 sub create_type_constraint_union         (@);
26 sub create_parameterized_type_constraint ($);
27 sub create_class_type_constraint         ($);
28
29 # dah sugah!
30 sub type        ($$;$$);
31 sub subtype     ($$;$$$);
32 sub class_type  ($);
33 sub coerce      ($@);
34 sub as          ($);
35 sub from        ($);
36 sub where       (&);
37 sub via         (&);
38 sub message     (&);
39 sub optimize_as (&);
40 sub enum        ($;@);
41
42 ## private stuff ...
43 sub _create_type_constraint ($$$;$$);
44 sub _install_type_coercions ($$);
45
46 ## --------------------------------------------------------
47
48 use Moose::Meta::TypeConstraint;
49 use Moose::Meta::TypeConstraint::Union;
50 use Moose::Meta::TypeConstraint::Parameterized;
51 use Moose::Meta::TypeCoercion;
52 use Moose::Meta::TypeCoercion::Union;
53 use Moose::Meta::TypeConstraint::Registry;
54 use Moose::Util::TypeConstraints::OptimizedConstraints;
55
56 my @exports = qw/
57     type subtype class_type as where message optimize_as
58     coerce from via
59     enum
60     find_type_constraint
61     register_type_constraint
62 /;
63
64 Sub::Exporter::setup_exporter({
65     exports => \@exports,
66     groups  => { default => [':all'] }
67 });
68
69 sub unimport {
70     no strict 'refs';
71     my $class = caller();
72     # loop through the exports ...
73     foreach my $name (@exports) {
74         # if we find one ...
75         if (defined &{$class . '::' . $name}) {
76             my $keyword = \&{$class . '::' . $name};
77
78             # make sure it is from Moose
79             my ($pkg_name) = Class::MOP::get_code_info($keyword);
80             next if $@;
81             next if $pkg_name ne 'Moose::Util::TypeConstraints';
82
83             # and if it is from Moose then undef the slot
84             delete ${$class . '::'}{$name};
85         }
86     }
87 }
88
89 ## --------------------------------------------------------
90 ## type registry and some useful functions for it
91 ## --------------------------------------------------------
92
93 my $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
94
95 sub get_type_constraint_registry         { $REGISTRY }
96 sub list_all_type_constraints            { keys %{$REGISTRY->type_constraints} }
97 sub export_type_constraints_as_functions {
98     my $pkg = caller();
99     no strict 'refs';
100     foreach my $constraint (keys %{$REGISTRY->type_constraints}) {
101         my $tc = $REGISTRY->get_type_constraint($constraint)->_compiled_type_constraint;
102         *{"${pkg}::${constraint}"} = sub { $tc->($_[0]) ? 1 : undef };
103     }
104 }
105
106 sub create_type_constraint_union (@) {
107     my @type_constraint_names;
108
109     if (scalar @_ == 1 && _detect_type_constraint_union($_[0])) {
110         @type_constraint_names = _parse_type_constraint_union($_[0]);
111     }
112     else {
113         @type_constraint_names = @_;
114     }
115
116     (scalar @type_constraint_names >= 2)
117         || confess "You must pass in at least 2 type names to make a union";
118
119     ($REGISTRY->has_type_constraint($_))
120         || confess "Could not locate type constraint ($_) for the union"
121             foreach @type_constraint_names;
122
123     return Moose::Meta::TypeConstraint::Union->new(
124         type_constraints => [
125             map {
126                 $REGISTRY->get_type_constraint($_)
127             } @type_constraint_names
128         ],
129     );
130 }
131
132 sub create_parameterized_type_constraint ($) {
133     my $type_constraint_name = shift;
134
135     my ($base_type, $type_parameter) = _parse_parameterized_type_constraint($type_constraint_name);
136
137     (defined $base_type && defined $type_parameter)
138         || confess "Could not parse type name ($type_constraint_name) correctly";
139
140     ($REGISTRY->has_type_constraint($base_type))
141         || confess "Could not locate the base type ($base_type)";
142
143     return Moose::Meta::TypeConstraint::Parameterized->new(
144         name           => $type_constraint_name,
145         parent         => $REGISTRY->get_type_constraint($base_type),
146         type_parameter => find_or_create_type_constraint(
147             $type_parameter => {
148                 parent     => $REGISTRY->get_type_constraint('Object'),
149                 constraint => sub { $_[0]->isa($type_parameter) }
150             }
151         ),
152     );
153 }
154
155 sub create_class_type_constraint ($) {
156     my $class = shift;
157
158     # too early for this check
159     #find_type_constraint("ClassName")->check($class)
160     #    || confess "Can't create a class type constraint because '$class' is not a class name";
161
162     Moose::Meta::TypeConstraint::Class->new( name => $class );
163 }
164
165 sub find_or_create_type_constraint ($;$) {
166     my ($type_constraint_name, $options_for_anon_type) = @_;
167
168     return $REGISTRY->get_type_constraint($type_constraint_name)
169         if $REGISTRY->has_type_constraint($type_constraint_name);
170
171     my $constraint;
172
173     if (_detect_type_constraint_union($type_constraint_name)) {
174         $constraint = create_type_constraint_union($type_constraint_name);
175     }
176     elsif (_detect_parameterized_type_constraint($type_constraint_name)) {
177         $constraint = create_parameterized_type_constraint($type_constraint_name);
178     }
179     else {
180         # NOTE:
181         # if there is no $options_for_anon_type 
182         # specified, then we assume they don't 
183         # want to create one, and return nothing.
184         return unless defined $options_for_anon_type;        
185
186         # NOTE:
187         # otherwise assume that we should create
188         # an ANON type with the $options_for_anon_type
189         # options which can be passed in. It should
190         # be noted that these don't get registered
191         # so we need to return it.
192         # - SL
193         return Moose::Meta::TypeConstraint->new(
194             name => '__ANON__',
195             %{$options_for_anon_type}
196         );
197     }
198
199     $REGISTRY->add_type_constraint($constraint);
200     return $constraint;
201 }
202
203 ## --------------------------------------------------------
204 ## exported functions ...
205 ## --------------------------------------------------------
206
207 sub find_type_constraint ($) { $REGISTRY->get_type_constraint(@_) }
208
209 sub register_type_constraint ($) {
210     my $constraint = shift;
211     confess "can't register an unnamed type constraint" unless defined $constraint->name;
212     $REGISTRY->add_type_constraint($constraint);
213 }
214
215 # type constructors
216
217 sub type ($$;$$) {
218     splice(@_, 1, 0, undef);
219     goto &_create_type_constraint;
220 }
221
222 sub subtype ($$;$$$) {
223     # NOTE:
224     # this adds an undef for the name
225     # if this is an anon-subtype:
226     #   subtype(Num => where { $_ % 2 == 0 }) # anon 'even' subtype
227     # but if the last arg is not a code
228     # ref then it is a subtype alias:
229     #   subtype(MyNumbers => as Num); # now MyNumbers is the same as Num
230     # ... yeah I know it's ugly code
231     # - SL
232     unshift @_ => undef if scalar @_ <= 2 && (reftype($_[1]) || '') eq 'CODE';
233     goto &_create_type_constraint;
234 }
235
236 sub class_type ($) {
237     register_type_constraint( create_class_type_constraint(shift) );
238 }
239
240 sub coerce ($@) {
241     my ($type_name, @coercion_map) = @_;
242     _install_type_coercions($type_name, \@coercion_map);
243 }
244
245 sub as      ($) { $_[0] }
246 sub from    ($) { $_[0] }
247 sub where   (&) { $_[0] }
248 sub via     (&) { $_[0] }
249
250 sub message     (&) { +{ message   => $_[0] } }
251 sub optimize_as (&) { +{ optimized => $_[0] } }
252
253 sub enum ($;@) {
254     my ($type_name, @values) = @_;
255     (scalar @values >= 2)
256         || confess "You must have at least two values to enumerate through";
257     my %valid = map { $_ => 1 } @values;
258     _create_type_constraint(
259         $type_name,
260         'Str',
261         sub { $valid{$_} }
262     );
263 }
264
265 ## --------------------------------------------------------
266 ## desugaring functions ...
267 ## --------------------------------------------------------
268
269 sub _create_type_constraint ($$$;$$) {
270     my $name   = shift;
271     my $parent = shift;
272     my $check  = shift;
273
274     my ($message, $optimized);
275     for (@_) {
276         $message   = $_->{message}   if exists $_->{message};
277         $optimized = $_->{optimized} if exists $_->{optimized};
278     }
279
280     my $pkg_defined_in = scalar(caller(0));
281
282     if (defined $name) {
283         my $type = $REGISTRY->get_type_constraint($name);
284
285         ($type->_package_defined_in eq $pkg_defined_in)
286             || confess ("The type constraint '$name' has already been created in "
287                        . $type->_package_defined_in . " and cannot be created again in "
288                        . $pkg_defined_in)
289                  if defined $type;
290     }
291
292     $parent = find_or_create_type_constraint($parent) if defined $parent;
293     
294     my $constraint = Moose::Meta::TypeConstraint->new(
295         name               => $name || '__ANON__',
296         package_defined_in => $pkg_defined_in,
297
298         ($parent    ? (parent     => $parent )   : ()),
299         ($check     ? (constraint => $check)     : ()),
300         ($message   ? (message    => $message)   : ()),
301         ($optimized ? (optimized  => $optimized) : ()),
302     );
303     
304     # NOTE:
305     # if we have a type constraint union, and no 
306     # type check, this means we are just aliasing
307     # the union constraint, which means we need to 
308     # handle this differently.
309     # - SL
310     if (not(defined $check) 
311         && $parent->isa('Moose::Meta::TypeConstraint::Union') 
312         && $parent->has_coercion 
313         ){
314         $constraint->coercion(Moose::Meta::TypeCoercion::Union->new(
315             type_constraint => $parent
316         ));
317     }    
318
319     $REGISTRY->add_type_constraint($constraint)
320         if defined $name;
321
322     return $constraint;
323 }
324
325 sub _install_type_coercions ($$) {
326     my ($type_name, $coercion_map) = @_;
327     my $type = $REGISTRY->get_type_constraint($type_name);
328     (defined $type)
329         || confess "Cannot find type '$type_name', perhaps you forgot to load it.";
330     if ($type->has_coercion) {
331         $type->coercion->add_type_coercions(@$coercion_map);
332     }
333     else {
334         my $type_coercion = Moose::Meta::TypeCoercion->new(
335             type_coercion_map => $coercion_map,
336             type_constraint   => $type
337         );
338         $type->coercion($type_coercion);
339     }
340 }
341
342 ## --------------------------------------------------------
343 ## type notation parsing ...
344 ## --------------------------------------------------------
345
346 {
347     # All I have to say is mugwump++ cause I know
348     # do not even have enough regexp-fu to be able
349     # to have written this (I can only barely
350     # understand it as it is)
351     # - SL
352
353     use re "eval";
354
355     my $valid_chars = qr{[\w:]};
356     my $type_atom   = qr{ $valid_chars+ };
357
358     my $type                = qr{  $valid_chars+  (?: \[  (??{$any})  \] )? }x;
359     my $type_capture_parts  = qr{ ($valid_chars+) (?: \[ ((??{$any})) \] )? }x;
360     my $type_with_parameter = qr{  $valid_chars+      \[  (??{$any})  \]    }x;
361
362     my $op_union = qr{ \s* \| \s* }x;
363     my $union    = qr{ $type (?: $op_union $type )+ }x;
364
365     our $any = qr{ $type | $union }x;
366
367     sub _parse_parameterized_type_constraint {
368         $_[0] =~ m{ $type_capture_parts }x;
369         return ($1, $2);
370     }
371
372     sub _detect_parameterized_type_constraint {
373         $_[0] =~ m{ ^ $type_with_parameter $ }x;
374     }
375
376     sub _parse_type_constraint_union {
377         my $given = shift;
378         my @rv;
379         while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
380                 push @rv => $1;
381         }
382         (pos($given) eq length($given))
383             || confess "'$given' didn't parse (parse-pos="
384                      . pos($given)
385                      . " and str-length="
386                      . length($given)
387                      . ")";
388         @rv;
389     }
390
391     sub _detect_type_constraint_union {
392         $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
393     }
394 }
395
396 ## --------------------------------------------------------
397 # define some basic built-in types
398 ## --------------------------------------------------------
399
400 type 'Any'  => where { 1 }; # meta-type including all
401 type 'Item' => where { 1 }; # base-type
402
403 subtype 'Undef'   => as 'Item' => where { !defined($_) };
404 subtype 'Defined' => as 'Item' => where {  defined($_) };
405
406 subtype 'Bool'
407     => as 'Item'
408     => where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
409
410 subtype 'Value'
411     => as 'Defined'
412     => where { !ref($_) }
413     => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
414
415 subtype 'Ref'
416     => as 'Defined'
417     => where {  ref($_) }
418     => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
419
420 subtype 'Str'
421     => as 'Value'
422     => where { 1 }
423     => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
424
425 subtype 'Num'
426     => as 'Value'
427     => where { Scalar::Util::looks_like_number($_) }
428     => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
429
430 subtype 'Int'
431     => as 'Num'
432     => where { "$_" =~ /^-?[0-9]+$/ }
433     => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
434
435 subtype 'ScalarRef' => as 'Ref' => where { ref($_) eq 'SCALAR' } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef;
436 subtype 'ArrayRef'  => as 'Ref' => where { ref($_) eq 'ARRAY'  } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef;
437 subtype 'HashRef'   => as 'Ref' => where { ref($_) eq 'HASH'   } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef;
438 subtype 'CodeRef'   => as 'Ref' => where { ref($_) eq 'CODE'   } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
439 subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
440 subtype 'GlobRef'   => as 'Ref' => where { ref($_) eq 'GLOB'   } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
441
442 # NOTE:
443 # scalar filehandles are GLOB refs,
444 # but a GLOB ref is not always a filehandle
445 subtype 'FileHandle'
446     => as 'GlobRef'
447     => where { Scalar::Util::openhandle($_) }
448     => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
449
450 # NOTE:
451 # blessed(qr/.../) returns true,.. how odd
452 subtype 'Object'
453     => as 'Ref'
454     => where { blessed($_) && blessed($_) ne 'Regexp' }
455     => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
456
457 subtype 'Role'
458     => as 'Object'
459     => where { $_->can('does') }
460     => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
461
462 my $_class_name_checker = sub {
463     return if ref($_[0]);
464     return unless defined($_[0]) && length($_[0]);
465
466     # walk the symbol table tree to avoid autovififying
467     # \*{${main::}{"Foo::"}} == \*main::Foo::
468
469     my $pack = \*::;
470     foreach my $part (split('::', $_[0])) {
471         return unless exists ${$$pack}{"${part}::"};
472         $pack = \*{${$$pack}{"${part}::"}};
473     }
474
475     # check for $VERSION or @ISA
476     return 1 if exists ${$$pack}{VERSION}
477              && defined *{${$$pack}{VERSION}}{SCALAR};
478     return 1 if exists ${$$pack}{ISA}
479              && defined *{${$$pack}{ISA}}{ARRAY};
480
481     # check for any method
482     foreach ( keys %{$$pack} ) {
483         next if substr($_, -2, 2) eq '::';
484         return 1 if defined *{${$$pack}{$_}}{CODE};
485     }
486
487     # fail
488     return;
489 };
490
491 subtype 'ClassName'
492     => as 'Str'
493     => $_class_name_checker # where ...
494     => { optimize => $_class_name_checker };
495
496 ## --------------------------------------------------------
497 # end of built-in types ...
498 ## --------------------------------------------------------
499
500 {
501     my @BUILTINS = list_all_type_constraints();
502     sub list_all_builtin_type_constraints { @BUILTINS }
503 }
504
505 1;
506
507 __END__
508
509 =pod
510
511 =head1 NAME
512
513 Moose::Util::TypeConstraints - Type constraint system for Moose
514
515 =head1 SYNOPSIS
516
517   use Moose::Util::TypeConstraints;
518
519   type 'Num' => where { Scalar::Util::looks_like_number($_) };
520
521   subtype 'Natural'
522       => as 'Num'
523       => where { $_ > 0 };
524
525   subtype 'NaturalLessThanTen'
526       => as 'Natural'
527       => where { $_ < 10 }
528       => message { "This number ($_) is not less than ten!" };
529
530   coerce 'Num'
531       => from 'Str'
532         => via { 0+$_ };
533
534   enum 'RGBColors' => qw(red green blue);
535
536 =head1 DESCRIPTION
537
538 This module provides Moose with the ability to create custom type
539 contraints to be used in attribute definition.
540
541 =head2 Important Caveat
542
543 This is B<NOT> a type system for Perl 5. These are type constraints,
544 and they are not used by Moose unless you tell it to. No type
545 inference is performed, expression are not typed, etc. etc. etc.
546
547 This is simply a means of creating small constraint functions which
548 can be used to simplify your own type-checking code.
549
550 =head2 Slightly Less Important Caveat
551
552 It is almost always a good idea to quote your type and subtype names.
553 This is to prevent perl from trying to execute the call as an indirect
554 object call. This issue only seems to come up when you have a subtype
555 the same name as a valid class, but when the issue does arise it tends
556 to be quite annoying to debug.
557
558 So for instance, this:
559
560   subtype DateTime => as Object => where { $_->isa('DateTime') };
561
562 will I<Just Work>, while this:
563
564   use DateTime;
565   subtype DateTime => as Object => where { $_->isa('DateTime') };
566
567 will fail silently and cause many headaches. The simple way to solve
568 this, as well as future proof your subtypes from classes which have
569 yet to have been created yet, is to simply do this:
570
571   use DateTime;
572   subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
573
574 =head2 Default Type Constraints
575
576 This module also provides a simple hierarchy for Perl 5 types, this
577 could probably use some work, but it works for me at the moment.
578
579   Any
580   Item
581       Bool
582       Undef
583       Defined
584           Value
585               Num
586                 Int
587               Str
588                 ClassName
589           Ref
590               ScalarRef
591               ArrayRef
592               HashRef
593               CodeRef
594               RegexpRef
595               GlobRef
596                 FileHandle
597               Object
598                   Role
599
600 Suggestions for improvement are welcome.
601
602 B<NOTE:> The C<Undef> type constraint does not work correctly
603 in every occasion, please use it sparringly.
604
605 B<NOTE:> The C<ClassName> type constraint is simply a subtype
606 of string which responds true to C<isa('UNIVERSAL')>. This means
607 that your class B<must> be loaded for this type constraint to
608 pass. I know this is not ideal for all, but it is a saner
609 restriction than most others.
610
611 =head2 Use with Other Constraint Modules
612
613 This module should play fairly nicely with other constraint
614 modules with only some slight tweaking. The C<where> clause
615 in types is expected to be a C<CODE> reference which checks
616 it's first argument and returns a bool. Since most constraint
617 modules work in a similar way, it should be simple to adapt
618 them to work with Moose.
619
620 For instance, this is how you could use it with
621 L<Declare::Constraints::Simple> to declare a completely new type.
622
623   type 'HashOfArrayOfObjects'
624       => IsHashRef(
625           -keys   => HasLength,
626           -values => IsArrayRef( IsObject ));
627
628 For more examples see the F<t/204_example_w_DCS.t> test file.
629
630 Here is an example of using L<Test::Deep> and it's non-test
631 related C<eq_deeply> function.
632
633   type 'ArrayOfHashOfBarsAndRandomNumbers'
634       => where {
635           eq_deeply($_,
636               array_each(subhashof({
637                   bar           => isa('Bar'),
638                   random_number => ignore()
639               })))
640         };
641
642 For a complete example see the F<t/205_example_w_TestDeep.t>
643 test file.
644
645 =head1 FUNCTIONS
646
647 =head2 Type Constraint Construction & Locating
648
649 =over 4
650
651 =item B<create_type_constraint_union ($pipe_seperated_types | @type_constraint_names)>
652
653 Given string with C<$pipe_seperated_types> or a list of C<@type_constraint_names>,
654 this will return a L<Moose::Meta::TypeConstraint::Union> instance.
655
656 =item B<create_parameterized_type_constraint ($type_name)>
657
658 Given a C<$type_name> in the form of:
659
660   BaseType[ContainerType]
661
662 this will extract the base type and container type and build an instance of
663 L<Moose::Meta::TypeConstraint::Parameterized> for it.
664
665 =item B<create_class_type_constraint ($class)>
666
667 Given a class name it will create a new L<Moose::Meta::TypeConstraint::Class>
668 object for that class name.
669
670 =item B<find_or_create_type_constraint ($type_name, ?$options_for_anon_type)>
671
672 This will attempt to find or create a type constraint given the a C<$type_name>.
673 If it cannot find it in the registry, it will see if it should be a union or
674 container type an create one if appropriate, and lastly if nothing can be
675 found or created that way, it will create an anon-type using the
676 C<$options_for_anon_type> HASH ref to populate it. If the C<$options_for_anon_type>
677 is not specified (it is C<undef>), then it will not create anything and simply
678 return.
679
680 =item B<find_type_constraint ($type_name)>
681
682 This function can be used to locate a specific type constraint
683 meta-object, of the class L<Moose::Meta::TypeConstraint> or a
684 derivative. What you do with it from there is up to you :)
685
686 =item B<register_type_constraint ($type_object)>
687
688 This function will register a named type constraint with the type registry.
689
690 =item B<get_type_constraint_registry>
691
692 Fetch the L<Moose::Meta::TypeConstraint::Registry> object which
693 keeps track of all type constraints.
694
695 =item B<list_all_type_constraints>
696
697 This will return a list of type constraint names, you can then
698 fetch them using C<find_type_constraint ($type_name)> if you
699 want to.
700
701 =item B<list_all_builtin_type_constraints>
702
703 This will return a list of builtin type constraints, meaning,
704 those which are defined in this module. See the section
705 labeled L<Default Type Constraints> for a complete list.
706
707 =item B<export_type_constraints_as_functions>
708
709 This will export all the current type constraints as functions
710 into the caller's namespace. Right now, this is mostly used for
711 testing, but it might prove useful to others.
712
713 =back
714
715 =head2 Type Constraint Constructors
716
717 The following functions are used to create type constraints.
718 They will then register the type constraints in a global store
719 where Moose can get to them if it needs to.
720
721 See the L<SYNOPSIS> for an example of how to use these.
722
723 =over 4
724
725 =item B<type ($name, $where_clause)>
726
727 This creates a base type, which has no parent.
728
729 =item B<subtype ($name, $parent, $where_clause, ?$message)>
730
731 This creates a named subtype.
732
733 =item B<subtype ($parent, $where_clause, ?$message)>
734
735 This creates an unnamed subtype and will return the type
736 constraint meta-object, which will be an instance of
737 L<Moose::Meta::TypeConstraint>.
738
739 =item B<class_type ($class)>
740
741 Creates a type constraint with the name C<$class> and the metaclass
742 L<Moose::Meta::TypeConstraint::Class>.
743
744 =item B<enum ($name, @values)>
745
746 This will create a basic subtype for a given set of strings.
747 The resulting constraint will be a subtype of C<Str> and
748 will match any of the items in C<@values>. It is case sensitive.
749 See the L<SYNOPSIS> for a simple example.
750
751 B<NOTE:> This is not a true proper enum type, it is simple
752 a convient constraint builder.
753
754 =item B<as>
755
756 This is just sugar for the type constraint construction syntax.
757
758 =item B<where>
759
760 This is just sugar for the type constraint construction syntax.
761
762 =item B<message>
763
764 This is just sugar for the type constraint construction syntax.
765
766 =item B<optimize_as>
767
768 This can be used to define a "hand optimized" version of your
769 type constraint which can be used to avoid traversing a subtype
770 constraint heirarchy.
771
772 B<NOTE:> You should only use this if you know what you are doing,
773 all the built in types use this, so your subtypes (assuming they
774 are shallow) will not likely need to use this.
775
776 =back
777
778 =head2 Type Coercion Constructors
779
780 Type constraints can also contain type coercions as well. If you
781 ask your accessor to coerce, then Moose will run the type-coercion
782 code first, followed by the type constraint check. This feature
783 should be used carefully as it is very powerful and could easily
784 take off a limb if you are not careful.
785
786 See the L<SYNOPSIS> for an example of how to use these.
787
788 =over 4
789
790 =item B<coerce>
791
792 =item B<from>
793
794 This is just sugar for the type coercion construction syntax.
795
796 =item B<via>
797
798 This is just sugar for the type coercion construction syntax.
799
800 =back
801
802 =head2 Namespace Management
803
804 =over 4
805
806 =item B<unimport>
807
808 This will remove all the type constraint keywords from the
809 calling class namespace.
810
811 =back
812
813 =head1 BUGS
814
815 All complex software has bugs lurking in it, and this module is no
816 exception. If you find a bug please either email me, or add the bug
817 to cpan-RT.
818
819 =head1 AUTHOR
820
821 Stevan Little E<lt>stevan@iinteractive.comE<gt>
822
823 =head1 COPYRIGHT AND LICENSE
824
825 Copyright 2006-2008 by Infinity Interactive, Inc.
826
827 L<http://www.iinteractive.com>
828
829 This library is free software; you can redistribute it and/or modify
830 it under the same terms as Perl itself.
831
832 =cut