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