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