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