2 package Moose::Util::TypeConstraints;
8 use Scalar::Util 'blessed';
11 our $VERSION = '0.57';
12 $VERSION = eval $VERSION;
13 our $AUTHORITY = 'cpan:STEVAN';
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
22 # creation and location
23 sub find_type_constraint ($);
24 sub register_type_constraint ($);
25 sub find_or_create_type_constraint ($;$);
26 sub find_or_parse_type_constraint ($);
27 sub find_or_create_isa_type_constraint ($);
28 sub find_or_create_does_type_constraint ($);
29 sub create_type_constraint_union (@);
30 sub create_parameterized_type_constraint ($);
31 sub create_class_type_constraint ($;$);
32 sub create_role_type_constraint ($;$);
33 sub create_enum_type_constraint ($$);
49 sub _create_type_constraint ($$$;$$);
50 sub _install_type_coercions ($$);
52 ## --------------------------------------------------------
54 use Moose::Meta::TypeConstraint;
55 use Moose::Meta::TypeConstraint::Union;
56 use Moose::Meta::TypeConstraint::Parameterized;
57 use Moose::Meta::TypeConstraint::Parameterizable;
58 use Moose::Meta::TypeConstraint::Class;
59 use Moose::Meta::TypeConstraint::Role;
60 use Moose::Meta::TypeConstraint::Enum;
61 use Moose::Meta::TypeCoercion;
62 use Moose::Meta::TypeCoercion::Union;
63 use Moose::Meta::TypeConstraint::Registry;
64 use Moose::Util::TypeConstraints::OptimizedConstraints;
66 Moose::Exporter->setup_import_methods(
69 type subtype class_type role_type as where message optimize_as
73 register_type_constraint )
78 ## --------------------------------------------------------
79 ## type registry and some useful functions for it
80 ## --------------------------------------------------------
82 my $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
84 sub get_type_constraint_registry { $REGISTRY }
85 sub list_all_type_constraints { keys %{$REGISTRY->type_constraints} }
86 sub export_type_constraints_as_functions {
89 foreach my $constraint (keys %{$REGISTRY->type_constraints}) {
90 my $tc = $REGISTRY->get_type_constraint($constraint)->_compiled_type_constraint;
91 *{"${pkg}::${constraint}"} = sub { $tc->($_[0]) ? 1 : undef }; # the undef is for compat
95 sub create_type_constraint_union (@) {
96 my @type_constraint_names;
98 if (scalar @_ == 1 && _detect_type_constraint_union($_[0])) {
99 @type_constraint_names = _parse_type_constraint_union($_[0]);
102 @type_constraint_names = @_;
105 (scalar @type_constraint_names >= 2)
106 || Moose->throw_error("You must pass in at least 2 type names to make a union");
108 my @type_constraints = sort {$a->name cmp $b->name} map {
109 find_or_parse_type_constraint($_) ||
110 Moose->throw_error("Could not locate type constraint ($_) for the union");
111 } @type_constraint_names;
113 return Moose::Meta::TypeConstraint::Union->new(
114 type_constraints => \@type_constraints
118 sub create_parameterized_type_constraint ($) {
119 my $type_constraint_name = shift;
120 my ($base_type, $type_parameter) = _parse_parameterized_type_constraint($type_constraint_name);
122 (defined $base_type && defined $type_parameter)
123 || Moose->throw_error("Could not parse type name ($type_constraint_name) correctly");
125 if ($REGISTRY->has_type_constraint($base_type)) {
126 my $base_type_tc = $REGISTRY->get_type_constraint($base_type);
127 return _create_parameterized_type_constraint(
132 Moose->throw_error("Could not locate the base type ($base_type)");
136 sub _create_parameterized_type_constraint {
137 my ( $base_type_tc, $type_parameter ) = @_;
138 if ( $base_type_tc->can('parameterize') ) {
139 return $base_type_tc->parameterize($type_parameter);
142 return Moose::Meta::TypeConstraint::Parameterized->new(
143 name => $base_type_tc->name . '[' . $type_parameter . ']',
144 parent => $base_type_tc,
146 find_or_create_isa_type_constraint($type_parameter),
151 #should we also support optimized checks?
152 sub create_class_type_constraint ($;$) {
153 my ( $class, $options ) = @_;
155 # too early for this check
156 #find_type_constraint("ClassName")->check($class)
157 # || Moose->throw_error("Can't create a class type constraint because '$class' is not a class name");
165 $options{name} ||= "__ANON__";
167 Moose::Meta::TypeConstraint::Class->new( %options );
170 sub create_role_type_constraint ($;$) {
171 my ( $role, $options ) = @_;
173 # too early for this check
174 #find_type_constraint("ClassName")->check($class)
175 # || Moose->throw_error("Can't create a class type constraint because '$class' is not a class name");
183 $options{name} ||= "__ANON__";
185 Moose::Meta::TypeConstraint::Role->new( %options );
189 sub find_or_create_type_constraint ($;$) {
190 my ( $type_constraint_name, $options_for_anon_type ) = @_;
192 if ( my $constraint = find_or_parse_type_constraint($type_constraint_name) ) {
195 elsif ( defined $options_for_anon_type ) {
197 # if there is no $options_for_anon_type
198 # specified, then we assume they don't
199 # want to create one, and return nothing.
201 # otherwise assume that we should create
202 # an ANON type with the $options_for_anon_type
203 # options which can be passed in. It should
204 # be noted that these don't get registered
205 # so we need to return it.
207 return Moose::Meta::TypeConstraint->new(
209 %{$options_for_anon_type}
216 sub find_or_create_isa_type_constraint ($) {
217 my $type_constraint_name = shift;
218 find_or_parse_type_constraint($type_constraint_name) || create_class_type_constraint($type_constraint_name)
221 sub find_or_create_does_type_constraint ($) {
222 my $type_constraint_name = shift;
223 find_or_parse_type_constraint($type_constraint_name) || create_role_type_constraint($type_constraint_name)
226 sub find_or_parse_type_constraint ($) {
227 my $type_constraint_name = normalize_type_constraint_name(shift);
230 if ($constraint = find_type_constraint($type_constraint_name)) {
232 } elsif (_detect_type_constraint_union($type_constraint_name)) {
233 $constraint = create_type_constraint_union($type_constraint_name);
234 } elsif (_detect_parameterized_type_constraint($type_constraint_name)) {
235 $constraint = create_parameterized_type_constraint($type_constraint_name);
240 $REGISTRY->add_type_constraint($constraint);
244 sub normalize_type_constraint_name {
245 my $type_constraint_name = shift @_;
246 $type_constraint_name =~ s/\s//g;
247 return $type_constraint_name;
250 ## --------------------------------------------------------
251 ## exported functions ...
252 ## --------------------------------------------------------
254 sub find_type_constraint ($) {
257 if ( blessed $type and $type->isa("Moose::Meta::TypeConstraint") ) {
261 return unless $REGISTRY->has_type_constraint($type);
262 return $REGISTRY->get_type_constraint($type);
266 sub register_type_constraint ($) {
267 my $constraint = shift;
268 Moose->throw_error("can't register an unnamed type constraint") unless defined $constraint->name;
269 $REGISTRY->add_type_constraint($constraint);
276 splice(@_, 1, 0, undef);
277 goto &_create_type_constraint;
280 sub subtype ($$;$$$) {
282 # this adds an undef for the name
283 # if this is an anon-subtype:
284 # subtype(Num => where { $_ % 2 == 0 }) # anon 'even' subtype
285 # but if the last arg is not a code
286 # ref then it is a subtype alias:
287 # subtype(MyNumbers => as Num); # now MyNumbers is the same as Num
288 # ... yeah I know it's ugly code
290 unshift @_ => undef if scalar @_ <= 2 && ('CODE' eq ref($_[1]));
291 goto &_create_type_constraint;
294 sub class_type ($;$) {
295 register_type_constraint(
296 create_class_type_constraint(
298 ( defined($_[1]) ? $_[1] : () ),
303 sub role_type ($;$) {
304 register_type_constraint(
305 create_role_type_constraint(
307 ( defined($_[1]) ? $_[1] : () ),
313 my ($type_name, @coercion_map) = @_;
314 _install_type_coercions($type_name, \@coercion_map);
318 sub from ($) { $_[0] }
319 sub where (&) { $_[0] }
320 sub via (&) { $_[0] }
322 sub message (&) { +{ message => $_[0] } }
323 sub optimize_as (&) { +{ optimized => $_[0] } }
326 my ($type_name, @values) = @_;
328 # if only an array-ref is passed then
329 # you get an anon-enum
331 if (ref $type_name eq 'ARRAY' && !@values) {
332 @values = @$type_name;
335 (scalar @values >= 2)
336 || Moose->throw_error("You must have at least two values to enumerate through");
337 my %valid = map { $_ => 1 } @values;
339 register_type_constraint(
340 create_enum_type_constraint(
347 sub create_enum_type_constraint ($$) {
348 my ( $type_name, $values ) = @_;
350 Moose::Meta::TypeConstraint::Enum->new(
351 name => $type_name || '__ANON__',
356 ## --------------------------------------------------------
357 ## desugaring functions ...
358 ## --------------------------------------------------------
360 sub _create_type_constraint ($$$;$$) {
365 my ($message, $optimized);
367 $message = $_->{message} if exists $_->{message};
368 $optimized = $_->{optimized} if exists $_->{optimized};
371 my $pkg_defined_in = scalar(caller(0));
374 my $type = $REGISTRY->get_type_constraint($name);
376 ($type->_package_defined_in eq $pkg_defined_in)
377 || confess ("The type constraint '$name' has already been created in "
378 . $type->_package_defined_in . " and cannot be created again in "
383 my $class = "Moose::Meta::TypeConstraint";
385 # FIXME should probably not be a special case
386 if ( defined $parent and $parent = find_or_parse_type_constraint($parent) ) {
387 $class = "Moose::Meta::TypeConstraint::Parameterizable"
388 if $parent->isa("Moose::Meta::TypeConstraint::Parameterizable");
391 my $constraint = $class->new(
392 name => $name || '__ANON__',
393 package_defined_in => $pkg_defined_in,
395 ($parent ? (parent => $parent ) : ()),
396 ($check ? (constraint => $check) : ()),
397 ($message ? (message => $message) : ()),
398 ($optimized ? (optimized => $optimized) : ()),
402 # if we have a type constraint union, and no
403 # type check, this means we are just aliasing
404 # the union constraint, which means we need to
405 # handle this differently.
407 if (not(defined $check)
408 && $parent->isa('Moose::Meta::TypeConstraint::Union')
409 && $parent->has_coercion
411 $constraint->coercion(Moose::Meta::TypeCoercion::Union->new(
412 type_constraint => $parent
416 $REGISTRY->add_type_constraint($constraint)
422 sub _install_type_coercions ($$) {
423 my ($type_name, $coercion_map) = @_;
424 my $type = find_type_constraint($type_name);
426 || Moose->throw_error("Cannot find type '$type_name', perhaps you forgot to load it.");
427 if ($type->has_coercion) {
428 $type->coercion->add_type_coercions(@$coercion_map);
431 my $type_coercion = Moose::Meta::TypeCoercion->new(
432 type_coercion_map => $coercion_map,
433 type_constraint => $type
435 $type->coercion($type_coercion);
439 ## --------------------------------------------------------
440 ## type notation parsing ...
441 ## --------------------------------------------------------
444 # All I have to say is mugwump++ cause I know
445 # do not even have enough regexp-fu to be able
446 # to have written this (I can only barely
447 # understand it as it is)
452 my $valid_chars = qr{[\w:]};
453 my $type_atom = qr{ $valid_chars+ };
457 my $type = qr{ $valid_chars+ (?: \[ \s* (??{$any}) \s* \] )? }x;
458 my $type_capture_parts = qr{ ($valid_chars+) (?: \[ \s* ((??{$any})) \s* \] )? }x;
459 my $type_with_parameter = qr{ $valid_chars+ \[ \s* (??{$any}) \s* \] }x;
461 my $op_union = qr{ \s* \| \s* }x;
462 my $union = qr{ $type (?: $op_union $type )+ }x;
464 ## New Stuff for structured types.
466 my $indirection = qr{=>};
467 my $divider_ops = qr{ $comma | $indirection }x;
468 my $structure_divider = qr{\s* $divider_ops \s*}x;
469 my $structure_elements = qr{ ($type $structure_divider*)+ }x;
471 $any = qr{ $type | $union | $structure_elements }x;
473 sub _parse_parameterized_type_constraint {
474 { no warnings 'void'; $any; } # force capture of interpolated lexical
475 my($base, $elements) = ($_[0] =~ m{ $type_capture_parts }x);
476 return ($base,$elements);
479 sub _detect_parameterized_type_constraint {
480 { no warnings 'void'; $any; } # force capture of interpolated lexical
481 $_[0] =~ m{ ^ $type_with_parameter $ }x;
484 sub _parse_type_constraint_union {
485 { no warnings 'void'; $any; } # force capture of interpolated lexical
488 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
491 (pos($given) eq length($given))
492 || Moose->throw_error("'$given' didn't parse (parse-pos="
500 sub _detect_type_constraint_union {
501 { no warnings 'void'; $any; } # force capture of interpolated lexical
502 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
506 ## --------------------------------------------------------
507 # define some basic built-in types
508 ## --------------------------------------------------------
510 type 'Any' => where { 1 }; # meta-type including all
511 type 'Item' => where { 1 }; # base-type
513 subtype 'Undef' => as 'Item' => where { !defined($_) };
514 subtype 'Defined' => as 'Item' => where { defined($_) };
518 => where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
522 => where { !ref($_) }
523 => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
528 => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
533 => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
537 => where { Scalar::Util::looks_like_number($_) }
538 => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
542 => where { "$_" =~ /^-?[0-9]+$/ }
543 => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
545 subtype 'ScalarRef' => as 'Ref' => where { ref($_) eq 'SCALAR' } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef;
546 subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
547 subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
548 subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
551 # scalar filehandles are GLOB refs,
552 # but a GLOB ref is not always a filehandle
555 => where { Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") ) }
556 => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
559 # blessed(qr/.../) returns true,.. how odd
562 => where { blessed($_) && blessed($_) ne 'Regexp' }
563 => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
567 => where { $_->can('does') }
568 => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
570 my $_class_name_checker = sub {
575 => where { Class::MOP::is_class_loaded($_) }
576 => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
578 ## --------------------------------------------------------
579 # parameterizable types ...
581 $REGISTRY->add_type_constraint(
582 Moose::Meta::TypeConstraint::Parameterizable->new(
584 package_defined_in => __PACKAGE__,
585 parent => find_type_constraint('Ref'),
586 constraint => sub { ref($_) eq 'ARRAY' },
587 optimized => \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
588 constraint_generator => sub {
589 my $type_parameter = shift;
590 my $check = $type_parameter->_compiled_type_constraint;
592 foreach my $x (@$_) {
593 ($check->($x)) || return
600 $REGISTRY->add_type_constraint(
601 Moose::Meta::TypeConstraint::Parameterizable->new(
603 package_defined_in => __PACKAGE__,
604 parent => find_type_constraint('Ref'),
605 constraint => sub { ref($_) eq 'HASH' },
606 optimized => \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
607 constraint_generator => sub {
608 my $type_parameter = shift;
609 my $check = $type_parameter->_compiled_type_constraint;
611 foreach my $x (values %$_) {
612 ($check->($x)) || return
619 $REGISTRY->add_type_constraint(
620 Moose::Meta::TypeConstraint::Parameterizable->new(
622 package_defined_in => __PACKAGE__,
623 parent => find_type_constraint('Item'),
624 constraint => sub { 1 },
625 constraint_generator => sub {
626 my $type_parameter = shift;
627 my $check = $type_parameter->_compiled_type_constraint;
629 return 1 if not(defined($_)) || $check->($_);
636 my @PARAMETERIZABLE_TYPES = map {
637 $REGISTRY->get_type_constraint($_)
638 } qw[ArrayRef HashRef Maybe];
640 sub get_all_parameterizable_types { @PARAMETERIZABLE_TYPES }
641 sub add_parameterizable_type {
643 (blessed $type && $type->isa('Moose::Meta::TypeConstraint::Parameterizable'))
644 || Moose->throw_error("Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type");
645 push @PARAMETERIZABLE_TYPES => $type;
648 ## --------------------------------------------------------
649 # end of built-in types ...
650 ## --------------------------------------------------------
653 my @BUILTINS = list_all_type_constraints();
654 sub list_all_builtin_type_constraints { @BUILTINS }
665 Moose::Util::TypeConstraints - Type constraint system for Moose
669 use Moose::Util::TypeConstraints;
671 type 'Num' => where { Scalar::Util::looks_like_number($_) };
677 subtype 'NaturalLessThanTen'
680 => message { "This number ($_) is not less than ten!" };
686 enum 'RGBColors' => qw(red green blue);
690 This module provides Moose with the ability to create custom type
691 contraints to be used in attribute definition.
693 =head2 Important Caveat
695 This is B<NOT> a type system for Perl 5. These are type constraints,
696 and they are not used by Moose unless you tell it to. No type
697 inference is performed, expression are not typed, etc. etc. etc.
699 This is simply a means of creating small constraint functions which
700 can be used to simplify your own type-checking code, with the added
701 side benefit of making your intentions clearer through self-documentation.
703 =head2 Slightly Less Important Caveat
705 It is B<always> a good idea to quote your type and subtype names.
707 This is to prevent perl from trying to execute the call as an indirect
708 object call. This issue only seems to come up when you have a subtype
709 the same name as a valid class, but when the issue does arise it tends
710 to be quite annoying to debug.
712 So for instance, this:
714 subtype DateTime => as Object => where { $_->isa('DateTime') };
716 will I<Just Work>, while this:
719 subtype DateTime => as Object => where { $_->isa('DateTime') };
721 will fail silently and cause many headaches. The simple way to solve
722 this, as well as future proof your subtypes from classes which have
723 yet to have been created yet, is to simply do this:
726 subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
728 =head2 Default Type Constraints
730 This module also provides a simple hierarchy for Perl 5 types, here is
731 that hierarchy represented visually.
755 B<NOTE:> Any type followed by a type parameter C<[`a]> can be
756 parameterized, this means you can say:
758 ArrayRef[Int] # an array of intergers
759 HashRef[CodeRef] # a hash of str to CODE ref mappings
760 Maybe[Str] # value may be a string, may be undefined
762 B<NOTE:> Unless you parameterize a type, then it is invalid to
763 include the square brackets. I.e. C<ArrayRef[]> will be
764 literally interpreted as a type name.
766 B<NOTE:> The C<Undef> type constraint for the most part works
767 correctly now, but edge cases may still exist, please use it
770 B<NOTE:> The C<ClassName> type constraint does a complex package
771 existence check. This means that your class B<must> be loaded for
772 this type constraint to pass. I know this is not ideal for all,
773 but it is a saner restriction than most others.
775 =head2 Type Constraint Naming
777 Since the types created by this module are global, it is suggested
778 that you namespace your types just as you would namespace your
779 modules. So instead of creating a I<Color> type for your B<My::Graphics>
780 module, you would call the type I<My::Graphics::Color> instead.
782 =head2 Use with Other Constraint Modules
784 This module should play fairly nicely with other constraint
785 modules with only some slight tweaking. The C<where> clause
786 in types is expected to be a C<CODE> reference which checks
787 it's first argument and returns a boolean. Since most constraint
788 modules work in a similar way, it should be simple to adapt
789 them to work with Moose.
791 For instance, this is how you could use it with
792 L<Declare::Constraints::Simple> to declare a completely new type.
794 type 'HashOfArrayOfObjects'
797 -values => IsArrayRef( IsObject ));
799 For more examples see the F<t/200_examples/204_example_w_DCS.t>
802 Here is an example of using L<Test::Deep> and it's non-test
803 related C<eq_deeply> function.
805 type 'ArrayOfHashOfBarsAndRandomNumbers'
808 array_each(subhashof({
810 random_number => ignore()
814 For a complete example see the
815 F<t/200_examples/205_example_w_TestDeep.t> test file.
819 =head2 Type Constraint Constructors
821 The following functions are used to create type constraints.
822 They will then register the type constraints in a global store
823 where Moose can get to them if it needs to.
825 See the L<SYNOPSIS> for an example of how to use these.
829 =item B<type ($name, $where_clause)>
831 This creates a base type, which has no parent.
833 =item B<subtype ($name, $parent, $where_clause, ?$message)>
835 This creates a named subtype.
837 =item B<subtype ($parent, $where_clause, ?$message)>
839 This creates an unnamed subtype and will return the type
840 constraint meta-object, which will be an instance of
841 L<Moose::Meta::TypeConstraint>.
843 =item B<class_type ($class, ?$options)>
845 Creates a type constraint with the name C<$class> and the metaclass
846 L<Moose::Meta::TypeConstraint::Class>.
848 =item B<role_type ($role, ?$options)>
850 Creates a type constraint with the name C<$role> and the metaclass
851 L<Moose::Meta::TypeConstraint::Role>.
853 =item B<enum ($name, @values)>
855 This will create a basic subtype for a given set of strings.
856 The resulting constraint will be a subtype of C<Str> and
857 will match any of the items in C<@values>. It is case sensitive.
858 See the L<SYNOPSIS> for a simple example.
860 B<NOTE:> This is not a true proper enum type, it is simple
861 a convient constraint builder.
863 =item B<enum (\@values)>
865 If passed an ARRAY reference instead of the C<$name>, C<@values> pair,
866 this will create an unnamed enum. This can then be used in an attribute
869 has 'sort_order' => (
871 isa => enum([qw[ ascending descending ]]),
876 This is just sugar for the type constraint construction syntax.
880 This is just sugar for the type constraint construction syntax.
882 Takes a block/code ref as an argument. When the type constraint is
883 tested, the supplied code is run with the value to be tested in
884 $_. This block should return true or false to indicate whether or not
885 the constraint check passed.
889 This is just sugar for the type constraint construction syntax.
891 Takes a block/code ref as an argument. When the type constraint fails,
892 then the code block is run (with the value provided in $_). This code
893 ref should return a string, which will be used in the text of the
898 This can be used to define a "hand optimized" version of your
899 type constraint which can be used to avoid traversing a subtype
900 constraint heirarchy.
902 B<NOTE:> You should only use this if you know what you are doing,
903 all the built in types use this, so your subtypes (assuming they
904 are shallow) will not likely need to use this.
908 =head2 Type Coercion Constructors
910 Type constraints can also contain type coercions as well. If you
911 ask your accessor to coerce, then Moose will run the type-coercion
912 code first, followed by the type constraint check. This feature
913 should be used carefully as it is very powerful and could easily
914 take off a limb if you are not careful.
916 See the L<SYNOPSIS> for an example of how to use these.
924 This is just sugar for the type coercion construction syntax.
928 This is just sugar for the type coercion construction syntax.
932 =head2 Type Constraint Construction & Locating
936 =item B<normalize_type_constraint_name ($type_constraint_name)>
938 Given a string that is expected to match a type constraint, will normalize the
939 string so that extra whitespace and newlines are removed.
941 =item B<create_type_constraint_union ($pipe_seperated_types | @type_constraint_names)>
943 Given string with C<$pipe_seperated_types> or a list of C<@type_constraint_names>,
944 this will return a L<Moose::Meta::TypeConstraint::Union> instance.
946 =item B<create_parameterized_type_constraint ($type_name)>
948 Given a C<$type_name> in the form of:
950 BaseType[ContainerType]
952 this will extract the base type and container type and build an instance of
953 L<Moose::Meta::TypeConstraint::Parameterized> for it.
955 =item B<create_class_type_constraint ($class, ?$options)>
957 Given a class name it will create a new L<Moose::Meta::TypeConstraint::Class>
958 object for that class name.
960 =item B<create_role_type_constraint ($role, ?$options)>
962 Given a role name it will create a new L<Moose::Meta::TypeConstraint::Role>
963 object for that role name.
965 =item B<create_enum_type_constraint ($name, $values)>
967 =item B<find_or_parse_type_constraint ($type_name)>
969 This will attempt to find or create a type constraint given the a C<$type_name>.
970 If it cannot find it in the registry, it will see if it should be a union or
971 container type an create one if appropriate
973 =item B<find_or_create_type_constraint ($type_name, ?$options_for_anon_type)>
975 This function will first call C<find_or_parse_type_constraint> with the type name.
977 If no type is found or created, but C<$options_for_anon_type> are provided, it
978 will create the corresponding type.
980 This was used by the C<does> and C<isa> parameters to L<Moose::Meta::Attribute>
981 and are now superseded by C<find_or_create_isa_type_constraint> and
982 C<find_or_create_does_type_constraint>.
984 =item B<find_or_create_isa_type_constraint ($type_name)>
986 =item B<find_or_create_does_type_constraint ($type_name)>
988 Attempts to parse the type name using L<find_or_parse_type_constraint> and if
989 no appropriate constraint is found will create a new anonymous one.
991 The C<isa> variant will use C<create_class_type_constraint> and the C<does>
992 variant will use C<create_role_type_constraint>.
994 =item B<find_type_constraint ($type_name)>
996 This function can be used to locate a specific type constraint
997 meta-object, of the class L<Moose::Meta::TypeConstraint> or a
998 derivative. What you do with it from there is up to you :)
1000 =item B<register_type_constraint ($type_object)>
1002 This function will register a named type constraint with the type registry.
1004 =item B<get_type_constraint_registry>
1006 Fetch the L<Moose::Meta::TypeConstraint::Registry> object which
1007 keeps track of all type constraints.
1009 =item B<list_all_type_constraints>
1011 This will return a list of type constraint names, you can then
1012 fetch them using C<find_type_constraint ($type_name)> if you
1015 =item B<list_all_builtin_type_constraints>
1017 This will return a list of builtin type constraints, meaning,
1018 those which are defined in this module. See the section
1019 labeled L<Default Type Constraints> for a complete list.
1021 =item B<export_type_constraints_as_functions>
1023 This will export all the current type constraints as functions
1024 into the caller's namespace. Right now, this is mostly used for
1025 testing, but it might prove useful to others.
1027 =item B<get_all_parameterizable_types>
1029 This returns all the parameterizable types that have been registered.
1031 =item B<add_parameterizable_type ($type)>
1033 Adds C<$type> to the list of parameterizable types
1037 =head1 Error Management
1043 If the caller is a Moose metaclass, use its L<Moose::Meta::Class/throw_error>
1044 routine, otherwise use L<Carp/confess>.
1048 =head2 Namespace Management
1054 This will remove all the type constraint keywords from the
1055 calling class namespace.
1061 All complex software has bugs lurking in it, and this module is no
1062 exception. If you find a bug please either email me, or add the bug
1067 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1069 =head1 COPYRIGHT AND LICENSE
1071 Copyright 2006-2008 by Infinity Interactive, Inc.
1073 L<http://www.iinteractive.com>
1075 This library is free software; you can redistribute it and/or modify
1076 it under the same terms as Perl itself.