2 package Moose::Util::TypeConstraints;
8 use List::MoreUtils qw( all any );
9 use Scalar::Util qw( blessed reftype );
12 our $VERSION = '0.73';
13 $VERSION = eval $VERSION;
14 our $AUTHORITY = 'cpan:STEVAN';
16 ## --------------------------------------------------------
17 # Prototyped subs must be predeclared because we have a
18 # circular dependency with Moose::Meta::Attribute et. al.
19 # so in case of us being use'd first the predeclaration
20 # ensures the prototypes are in scope when consumers are
29 ## --------------------------------------------------------
31 use Moose::Meta::TypeConstraint;
32 use Moose::Meta::TypeConstraint::Union;
33 use Moose::Meta::TypeConstraint::Parameterized;
34 use Moose::Meta::TypeConstraint::Parameterizable;
35 use Moose::Meta::TypeConstraint::Class;
36 use Moose::Meta::TypeConstraint::Role;
37 use Moose::Meta::TypeConstraint::Enum;
38 use Moose::Meta::TypeCoercion;
39 use Moose::Meta::TypeCoercion::Union;
40 use Moose::Meta::TypeConstraint::Registry;
41 use Moose::Util::TypeConstraints::OptimizedConstraints;
43 Moose::Exporter->setup_import_methods(
46 type subtype class_type role_type maybe_type duck_type
47 as where message optimize_as
51 register_type_constraint )
56 ## --------------------------------------------------------
57 ## type registry and some useful functions for it
58 ## --------------------------------------------------------
60 my $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
62 sub get_type_constraint_registry {$REGISTRY}
63 sub list_all_type_constraints { keys %{ $REGISTRY->type_constraints } }
65 sub export_type_constraints_as_functions {
68 foreach my $constraint ( keys %{ $REGISTRY->type_constraints } ) {
69 my $tc = $REGISTRY->get_type_constraint($constraint)
70 ->_compiled_type_constraint;
71 *{"${pkg}::${constraint}"}
72 = sub { $tc->( $_[0] ) ? 1 : undef }; # the undef is for compat
76 sub create_type_constraint_union {
77 my @type_constraint_names;
79 if ( scalar @_ == 1 && _detect_type_constraint_union( $_[0] ) ) {
80 @type_constraint_names = _parse_type_constraint_union( $_[0] );
83 @type_constraint_names = @_;
86 ( scalar @type_constraint_names >= 2 )
87 || __PACKAGE__->_throw_error(
88 "You must pass in at least 2 type names to make a union");
90 my @type_constraints = map {
91 find_or_parse_type_constraint($_)
92 || __PACKAGE__->_throw_error(
93 "Could not locate type constraint ($_) for the union");
94 } @type_constraint_names;
96 return Moose::Meta::TypeConstraint::Union->new(
97 type_constraints => \@type_constraints );
100 sub create_parameterized_type_constraint {
101 my $type_constraint_name = shift;
102 my ( $base_type, $type_parameter )
103 = _parse_parameterized_type_constraint($type_constraint_name);
105 ( defined $base_type && defined $type_parameter )
106 || __PACKAGE__->_throw_error(
107 "Could not parse type name ($type_constraint_name) correctly");
109 if ( $REGISTRY->has_type_constraint($base_type) ) {
110 my $base_type_tc = $REGISTRY->get_type_constraint($base_type);
111 return _create_parameterized_type_constraint(
117 __PACKAGE__->_throw_error(
118 "Could not locate the base type ($base_type)");
122 sub _create_parameterized_type_constraint {
123 my ( $base_type_tc, $type_parameter ) = @_;
124 if ( $base_type_tc->can('parameterize') ) {
125 return $base_type_tc->parameterize($type_parameter);
128 return Moose::Meta::TypeConstraint::Parameterized->new(
129 name => $base_type_tc->name . '[' . $type_parameter . ']',
130 parent => $base_type_tc,
132 find_or_create_isa_type_constraint($type_parameter),
137 #should we also support optimized checks?
138 sub create_class_type_constraint {
139 my ( $class, $options ) = @_;
141 # too early for this check
142 #find_type_constraint("ClassName")->check($class)
143 # || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
151 $options{name} ||= "__ANON__";
153 Moose::Meta::TypeConstraint::Class->new(%options);
156 sub create_role_type_constraint {
157 my ( $role, $options ) = @_;
159 # too early for this check
160 #find_type_constraint("ClassName")->check($class)
161 # || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
169 $options{name} ||= "__ANON__";
171 Moose::Meta::TypeConstraint::Role->new(%options);
174 sub find_or_create_type_constraint {
175 my ( $type_constraint_name, $options_for_anon_type ) = @_;
178 = find_or_parse_type_constraint($type_constraint_name) ) {
181 elsif ( defined $options_for_anon_type ) {
184 # if there is no $options_for_anon_type
185 # specified, then we assume they don't
186 # want to create one, and return nothing.
188 # otherwise assume that we should create
189 # an ANON type with the $options_for_anon_type
190 # options which can be passed in. It should
191 # be noted that these don't get registered
192 # so we need to return it.
194 return Moose::Meta::TypeConstraint->new(
196 %{$options_for_anon_type}
203 sub find_or_create_isa_type_constraint {
204 my $type_constraint_name = shift;
205 find_or_parse_type_constraint($type_constraint_name)
206 || create_class_type_constraint($type_constraint_name);
209 sub find_or_create_does_type_constraint {
210 my $type_constraint_name = shift;
211 find_or_parse_type_constraint($type_constraint_name)
212 || create_role_type_constraint($type_constraint_name);
215 sub find_or_parse_type_constraint {
216 my $type_constraint_name = normalize_type_constraint_name(shift);
219 if ( $constraint = find_type_constraint($type_constraint_name) ) {
222 elsif ( _detect_type_constraint_union($type_constraint_name) ) {
223 $constraint = create_type_constraint_union($type_constraint_name);
225 elsif ( _detect_parameterized_type_constraint($type_constraint_name) ) {
227 = create_parameterized_type_constraint($type_constraint_name);
233 $REGISTRY->add_type_constraint($constraint);
237 sub normalize_type_constraint_name {
238 my $type_constraint_name = shift;
239 $type_constraint_name =~ s/\s//g;
240 return $type_constraint_name;
246 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
247 Carp::confess($error);
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 __PACKAGE__->_throw_error("can't register an unnamed type constraint")
269 unless defined $constraint->name;
270 $REGISTRY->add_type_constraint($constraint);
278 # back-compat version, called without sugar
279 if ( !any { ( reftype($_) || '' ) eq 'HASH' } @_ ) {
280 return _create_type_constraint( $_[0], undef, $_[1] );
285 my %p = map { %{$_} } @_;
287 return _create_type_constraint(
288 $name, undef, $p{where}, $p{message},
295 # crazy back-compat code for being called without sugar ...
297 # subtype 'Parent', sub { where };
298 if ( scalar @_ == 2 && ( reftype( $_[1] ) || '' ) eq 'CODE' ) {
299 return _create_type_constraint( undef, @_ );
302 # subtype 'Parent', sub { where }, sub { message };
303 # subtype 'Parent', sub { where }, sub { message }, sub { optimized };
304 if ( scalar @_ >= 3 && all { ( reftype($_) || '' ) eq 'CODE' }
306 return _create_type_constraint( undef, @_ );
309 # subtype 'Name', 'Parent', ...
310 if ( scalar @_ >= 2 && all { !ref } @_[ 0, 1 ] ) {
311 return _create_type_constraint(@_);
314 if ( @_ == 1 && !ref $_[0] ) {
315 __PACKAGE__->_throw_error(
316 'A subtype cannot consist solely of a name, it must have a parent'
320 # The blessed check is mostly to accommodate MooseX::Types, which
321 # uses an object which overloads stringification as a type name.
322 my $name = ref $_[0] && !blessed $_[0] ? undef : shift;
324 my %p = map { %{$_} } @_;
326 # subtype Str => where { ... };
327 if ( !exists $p{as} ) {
332 return _create_type_constraint(
333 $name, $p{as}, $p{where}, $p{message},
339 register_type_constraint(
340 create_class_type_constraint(
342 ( defined( $_[1] ) ? $_[1] : () ),
347 sub role_type ($;$) {
348 register_type_constraint(
349 create_role_type_constraint(
351 ( defined( $_[1] ) ? $_[1] : () ),
357 my ($type_parameter) = @_;
359 register_type_constraint(
360 $REGISTRY->get_type_constraint('Maybe')->parameterize($type_parameter)
365 my ($type_name, @methods) = @_;
366 if ( ref $type_name eq 'ARRAY' && !@methods ) {
367 @methods = @$type_name;
371 register_type_constraint(
372 _create_type_constraint(
373 $type_name, 'Object',
376 my @missing_methods = grep { !$obj->can($_) } @methods;
377 return ! scalar @missing_methods;
381 my @missing_methods = grep { !$obj->can($_) } @methods;
383 "${\blessed($obj)} is missing methods '@missing_methods'";
390 my ( $type_name, @coercion_map ) = @_;
391 _install_type_coercions( $type_name, \@coercion_map );
394 # The trick of returning @_ lets us avoid having to specify a
395 # prototype. Perl will parse this:
403 # subtype( 'Foo', as( 'Str', where { ... } ) );
405 # If as() returns all it's extra arguments, this just works, and
406 # preserves backwards compatibility.
407 sub as { { as => shift }, @_ }
408 sub where (&) { { where => $_[0] } }
409 sub message (&) { { message => $_[0] } }
410 sub optimize_as (&) { { optimize_as => $_[0] } }
413 sub via (&) { $_[0] }
416 my ( $type_name, @values ) = @_;
419 # if only an array-ref is passed then
420 # you get an anon-enum
422 if ( ref $type_name eq 'ARRAY' && !@values ) {
423 @values = @$type_name;
426 ( scalar @values >= 2 )
427 || __PACKAGE__->_throw_error(
428 "You must have at least two values to enumerate through");
429 my %valid = map { $_ => 1 } @values;
431 register_type_constraint(
432 create_enum_type_constraint(
439 sub create_enum_type_constraint {
440 my ( $type_name, $values ) = @_;
442 Moose::Meta::TypeConstraint::Enum->new(
443 name => $type_name || '__ANON__',
448 ## --------------------------------------------------------
449 ## desugaring functions ...
450 ## --------------------------------------------------------
452 sub _create_type_constraint ($$$;$$) {
457 my $optimized = shift;
459 my $pkg_defined_in = scalar( caller(1) );
461 if ( defined $name ) {
462 my $type = $REGISTRY->get_type_constraint($name);
464 ( $type->_package_defined_in eq $pkg_defined_in )
466 "The type constraint '$name' has already been created in "
467 . $type->_package_defined_in
468 . " and cannot be created again in "
472 $name =~ /^[\w:\.]+$/
473 or die qq{$name contains invalid characters for a type name.}
474 . qq{ Names can contain alphanumeric character, ":", and "."\n};
479 package_defined_in => $pkg_defined_in,
481 ( $check ? ( constraint => $check ) : () ),
482 ( $message ? ( message => $message ) : () ),
483 ( $optimized ? ( optimized => $optimized ) : () ),
492 : find_or_create_isa_type_constraint($parent)
494 $constraint = $parent->create_child_type(%opts);
497 $constraint = Moose::Meta::TypeConstraint->new(%opts);
500 $REGISTRY->add_type_constraint($constraint)
506 sub _install_type_coercions ($$) {
507 my ( $type_name, $coercion_map ) = @_;
508 my $type = find_type_constraint($type_name);
510 || __PACKAGE__->_throw_error(
511 "Cannot find type '$type_name', perhaps you forgot to load it.");
512 if ( $type->has_coercion ) {
513 $type->coercion->add_type_coercions(@$coercion_map);
516 my $type_coercion = Moose::Meta::TypeCoercion->new(
517 type_coercion_map => $coercion_map,
518 type_constraint => $type
520 $type->coercion($type_coercion);
524 ## --------------------------------------------------------
525 ## type notation parsing ...
526 ## --------------------------------------------------------
530 # All I have to say is mugwump++ cause I know
531 # do not even have enough regexp-fu to be able
532 # to have written this (I can only barely
533 # understand it as it is)
538 my $valid_chars = qr{[\w:\.]};
539 my $type_atom = qr{ $valid_chars+ };
543 my $type = qr{ $valid_chars+ (?: \[ \s* (??{$any}) \s* \] )? }x;
544 my $type_capture_parts
545 = qr{ ($valid_chars+) (?: \[ \s* ((??{$any})) \s* \] )? }x;
546 my $type_with_parameter
547 = qr{ $valid_chars+ \[ \s* (??{$any}) \s* \] }x;
549 my $op_union = qr{ \s* \| \s* }x;
550 my $union = qr{ $type (?: $op_union $type )+ }x;
552 $any = qr{ $type | $union }x;
554 sub _parse_parameterized_type_constraint {
555 { no warnings 'void'; $any; } # force capture of interpolated lexical
556 $_[0] =~ m{ $type_capture_parts }x;
560 sub _detect_parameterized_type_constraint {
561 { no warnings 'void'; $any; } # force capture of interpolated lexical
562 $_[0] =~ m{ ^ $type_with_parameter $ }x;
565 sub _parse_type_constraint_union {
566 { no warnings 'void'; $any; } # force capture of interpolated lexical
569 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
572 ( pos($given) eq length($given) )
573 || __PACKAGE__->_throw_error( "'$given' didn't parse (parse-pos="
581 sub _detect_type_constraint_union {
582 { no warnings 'void'; $any; } # force capture of interpolated lexical
583 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
587 ## --------------------------------------------------------
588 # define some basic built-in types
589 ## --------------------------------------------------------
591 # By making these classes immutable before creating all the types we
592 # below, we avoid repeatedly calling the slow MOP-based accessors.
594 inline_constructor => 1,
595 constructor_name => "_new",
597 # these are Class::MOP accessors, so they need inlining
598 inline_accessors => 1
599 ) for grep { $_->is_mutable }
602 Moose::Meta::TypeConstraint
603 Moose::Meta::TypeConstraint::Union
604 Moose::Meta::TypeConstraint::Parameterized
605 Moose::Meta::TypeConstraint::Parameterizable
606 Moose::Meta::TypeConstraint::Class
607 Moose::Meta::TypeConstraint::Role
608 Moose::Meta::TypeConstraint::Enum
609 Moose::Meta::TypeConstraint::Registry
612 type 'Any' => where {1}; # meta-type including all
613 type 'Item' => where {1}; # base-type
615 subtype 'Undef' => as 'Item' => where { !defined($_) };
616 subtype 'Defined' => as 'Item' => where { defined($_) };
618 subtype 'Bool' => as 'Item' =>
619 where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
621 subtype 'Value' => as 'Defined' => where { !ref($_) } =>
622 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
624 subtype 'Ref' => as 'Defined' => where { ref($_) } =>
625 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
627 subtype 'Str' => as 'Value' => where {1} =>
628 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
630 subtype 'Num' => as 'Value' =>
631 where { Scalar::Util::looks_like_number($_) } =>
632 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
634 subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } =>
635 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
637 subtype 'ScalarRef' => as 'Ref' => where { ref($_) eq 'SCALAR' } =>
639 \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef;
640 subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
641 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
642 subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } =>
644 \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
645 subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
646 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
649 # scalar filehandles are GLOB refs,
650 # but a GLOB ref is not always a filehandle
651 subtype 'FileHandle' => as 'GlobRef' => where {
652 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
654 \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
657 # blessed(qr/.../) returns true,.. how odd
658 subtype 'Object' => as 'Ref' =>
659 where { blessed($_) && blessed($_) ne 'Regexp' } =>
660 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
662 subtype 'Role' => as 'Object' => where { $_->can('does') } =>
663 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
665 my $_class_name_checker = sub { };
667 subtype 'ClassName' => as 'Str' =>
668 where { Class::MOP::is_class_loaded($_) } => optimize_as
669 \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
671 subtype 'RoleName' => as 'ClassName' => where {
672 ( ( $_->can('meta') || return )->($_) || return )
673 ->isa('Moose::Meta::Role');
675 \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
677 ## --------------------------------------------------------
678 # parameterizable types ...
680 $REGISTRY->add_type_constraint(
681 Moose::Meta::TypeConstraint::Parameterizable->new(
683 package_defined_in => __PACKAGE__,
684 parent => find_type_constraint('Ref'),
685 constraint => sub { ref($_) eq 'ARRAY' },
687 \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
688 constraint_generator => sub {
689 my $type_parameter = shift;
690 my $check = $type_parameter->_compiled_type_constraint;
692 foreach my $x (@$_) {
693 ( $check->($x) ) || return;
701 $REGISTRY->add_type_constraint(
702 Moose::Meta::TypeConstraint::Parameterizable->new(
704 package_defined_in => __PACKAGE__,
705 parent => find_type_constraint('Ref'),
706 constraint => sub { ref($_) eq 'HASH' },
708 \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
709 constraint_generator => sub {
710 my $type_parameter = shift;
711 my $check = $type_parameter->_compiled_type_constraint;
713 foreach my $x ( values %$_ ) {
714 ( $check->($x) ) || return;
722 $REGISTRY->add_type_constraint(
723 Moose::Meta::TypeConstraint::Parameterizable->new(
725 package_defined_in => __PACKAGE__,
726 parent => find_type_constraint('Item'),
727 constraint => sub {1},
728 constraint_generator => sub {
729 my $type_parameter = shift;
730 my $check = $type_parameter->_compiled_type_constraint;
732 return 1 if not( defined($_) ) || $check->($_);
739 my @PARAMETERIZABLE_TYPES
740 = map { $REGISTRY->get_type_constraint($_) } qw[ArrayRef HashRef Maybe];
742 sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
744 sub add_parameterizable_type {
747 && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
748 || __PACKAGE__->_throw_error(
749 "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
751 push @PARAMETERIZABLE_TYPES => $type;
754 ## --------------------------------------------------------
755 # end of built-in types ...
756 ## --------------------------------------------------------
759 my @BUILTINS = list_all_type_constraints();
760 sub list_all_builtin_type_constraints {@BUILTINS}
767 goto &Moose::throw_error;
778 Moose::Util::TypeConstraints - Type constraint system for Moose
782 use Moose::Util::TypeConstraints;
788 subtype 'NaturalLessThanTen'
791 => message { "This number ($_) is not less than ten!" };
797 enum 'RGBColors' => qw(red green blue);
799 no Moose::Util::TypeConstraints;
803 This module provides Moose with the ability to create custom type
804 constraints to be used in attribute definition.
806 =head2 Important Caveat
808 This is B<NOT> a type system for Perl 5. These are type constraints,
809 and they are not used by Moose unless you tell it to. No type
810 inference is performed, expressions are not typed, etc. etc. etc.
812 A type constraint is at heart a small "check if a value is valid"
813 function. A constraint can be associated with an attribute. This
814 simplifies parameter validation, and makes your code clearer to read,
815 because you can refer to constraints by name.
817 =head2 Slightly Less Important Caveat
819 It is B<always> a good idea to quote your type names.
821 This prevents Perl from trying to execute the call as an indirect
822 object call. This can be an issue when you have a subtype with the
823 same name as a valid class.
827 subtype DateTime => as Object => where { $_->isa('DateTime') };
829 will I<just work>, while this:
832 subtype DateTime => as Object => where { $_->isa('DateTime') };
834 will fail silently and cause many headaches. The simple way to solve
835 this, as well as future proof your subtypes from classes which have
836 yet to have been created, is to quote the type name:
839 subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
841 =head2 Default Type Constraints
843 This module also provides a simple hierarchy for Perl 5 types, here is
844 that hierarchy represented visually.
869 B<NOTE:> Any type followed by a type parameter C<[`a]> can be
870 parameterized, this means you can say:
872 ArrayRef[Int] # an array of integers
873 HashRef[CodeRef] # a hash of str to CODE ref mappings
874 Maybe[Str] # value may be a string, may be undefined
876 If Moose finds a name in brackets that it does not recognize as an
877 existing type, it assumes that this is a class name, for example
878 C<ArrayRef[DateTime]>.
880 B<NOTE:> Unless you parameterize a type, then it is invalid to include
881 the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
882 name, I<not> as a parameterization of C<ArrayRef>.
884 B<NOTE:> The C<Undef> type constraint for the most part works
885 correctly now, but edge cases may still exist, please use it
888 B<NOTE:> The C<ClassName> type constraint does a complex package
889 existence check. This means that your class B<must> be loaded for this
890 type constraint to pass.
892 B<NOTE:> The C<RoleName> constraint checks a string is a I<package
893 name> which is a role, like C<'MyApp::Role::Comparable'>. The C<Role>
894 constraint checks that an I<object does> the named role.
896 =head2 Type Constraint Naming
898 Type name declared via this module can only contain alphanumeric
899 characters, colons (:), and periods (.).
901 Since the types created by this module are global, it is suggested
902 that you namespace your types just as you would namespace your
903 modules. So instead of creating a I<Color> type for your
904 B<My::Graphics> module, you would call the type
905 I<My::Graphics::Types::Color> instead.
907 =head2 Use with Other Constraint Modules
909 This module can play nicely with other constraint modules with some
910 slight tweaking. The C<where> clause in types is expected to be a
911 C<CODE> reference which checks it's first argument and returns a
912 boolean. Since most constraint modules work in a similar way, it
913 should be simple to adapt them to work with Moose.
915 For instance, this is how you could use it with
916 L<Declare::Constraints::Simple> to declare a completely new type.
918 type 'HashOfArrayOfObjects',
922 -values => IsArrayRef(IsObject)
926 For more examples see the F<t/200_examples/004_example_w_DCS.t> test
929 Here is an example of using L<Test::Deep> and it's non-test
930 related C<eq_deeply> function.
932 type 'ArrayOfHashOfBarsAndRandomNumbers'
935 array_each(subhashof({
937 random_number => ignore()
941 For a complete example see the
942 F<t/200_examples/005_example_w_TestDeep.t> test file.
946 =head2 Type Constraint Constructors
948 The following functions are used to create type constraints. They
949 will also register the type constraints your create in a global
950 registry that is used to look types up by name.
952 See the L<SYNOPSIS> for an example of how to use these.
956 =item B<subtype 'Name' => as 'Parent' => where { } ...>
958 This creates a named subtype.
960 If you provide a parent that Moose does not recognize, it will
961 automatically create a new class type constraint for this name.
963 When creating a named type, the C<subtype> function should either be
964 called with the sugar helpers (C<where>, C<message>, etc), or with a
965 name and a hashref of parameters:
967 subtype( 'Foo', { where => ..., message => ... } );
969 The valid hashref keys are C<as> (the parent), C<where>, C<message>,
972 =item B<subtype as 'Parent' => where { } ...>
974 This creates an unnamed subtype and will return the type
975 constraint meta-object, which will be an instance of
976 L<Moose::Meta::TypeConstraint>.
978 When creating an anonymous type, the C<subtype> function should either
979 be called with the sugar helpers (C<where>, C<message>, etc), or with
980 just a hashref of parameters:
982 subtype( { where => ..., message => ... } );
984 =item B<class_type ($class, ?$options)>
986 Creates a new subtype of C<Object> with the name C<$class> and the
987 metaclass L<Moose::Meta::TypeConstraint::Class>.
989 =item B<role_type ($role, ?$options)>
991 Creates a C<Role> type constraint with the name C<$role> and the
992 metaclass L<Moose::Meta::TypeConstraint::Role>.
994 =item B<maybe_type ($type)>
996 Creates a type constraint for either C<undef> or something of the
999 =item B<duck_type ($name, @methods)>
1001 This will create a subtype of Object and test to make sure the value
1002 C<can()> do the methods in C<@methods>.
1004 This is intended as an easy way to accept non-Moose objects that
1005 provide a certain interface. If you're using Moose classes, we
1006 recommend that you use a C<requires>-only Role instead.
1008 =item B<duck_type (\@methods)>
1010 If passed an ARRAY reference instead of the C<$name>, C<@methods>
1011 pair, this will create an unnamed duck type. This can be used in an
1012 attribute definiton like so:
1016 isa => duck_type( [qw( get_set )] ),
1019 =item B<enum ($name, @values)>
1021 This will create a basic subtype for a given set of strings.
1022 The resulting constraint will be a subtype of C<Str> and
1023 will match any of the items in C<@values>. It is case sensitive.
1024 See the L<SYNOPSIS> for a simple example.
1026 B<NOTE:> This is not a true proper enum type, it is simply
1027 a convenient constraint builder.
1029 =item B<enum (\@values)>
1031 If passed an ARRAY reference instead of the C<$name>, C<@values> pair,
1032 this will create an unnamed enum. This can then be used in an attribute
1035 has 'sort_order' => (
1037 isa => enum([qw[ ascending descending ]]),
1040 =item B<as 'Parent'>
1042 This is just sugar for the type constraint construction syntax.
1044 It takes a single argument, which is the name of a parent type.
1046 =item B<where { ... }>
1048 This is just sugar for the type constraint construction syntax.
1050 It takes a subroutine reference as an argument. When the type
1051 constraint is tested, the reference is run with the value to be tested
1052 in C<$_>. This reference should return true or false to indicate
1053 whether or not the constraint check passed.
1055 =item B<message { ... }>
1057 This is just sugar for the type constraint construction syntax.
1059 It takes a subroutine reference as an argument. When the type
1060 constraint fails, then the code block is run with the value provided
1061 in C<$_>. This reference should return a string, which will be used in
1062 the text of the exception thrown.
1064 =item B<optimize_as { ... }>
1066 This can be used to define a "hand optimized" version of your
1067 type constraint which can be used to avoid traversing a subtype
1068 constraint hierarchy.
1070 B<NOTE:> You should only use this if you know what you are doing,
1071 all the built in types use this, so your subtypes (assuming they
1072 are shallow) will not likely need to use this.
1074 =item B<type 'Name' => where { } ... >
1076 This creates a base type, which has no parent.
1078 The C<type> function should either be called with the sugar helpers
1079 (C<where>, C<message>, etc), or with a name and a hashref of
1082 type( 'Foo', { where => ..., message => ... } );
1084 The valid hashref keys are C<where>, C<message>, and C<optimize_as>.
1088 =head2 Type Coercion Constructors
1090 You can define coercions for type constraints, which allow you to
1091 automatically transform values to something valid for the type
1092 constraint. If you ask your accessor to coerce, then Moose will run
1093 the type-coercion code first, followed by the type constraint
1094 check. This feature should be used carefully as it is very powerful
1095 and could easily take off a limb if you are not careful.
1097 See the L<SYNOPSIS> for an example of how to use these.
1101 =item B<< coerce 'Name' => from 'OtherName' => via { ... } >>
1103 This defines a coercion from one type to another. The C<Name> argument
1104 is the type you are coercing I<to>.
1106 =item B<from 'OtherName'>
1108 This is just sugar for the type coercion construction syntax.
1110 It takes a single type name (or type object), which is the type being
1113 =item B<via { ... }>
1115 This is just sugar for the type coercion construction syntax.
1117 It takes a subroutine reference. This reference will be called with
1118 the value to be coerced in C<$_>. It is expected to return a new value
1119 of the proper type for the coercion.
1123 =head2 Creating and Finding Type Constraints
1125 These are additional functions for creating and finding type
1126 constraints. Most of these functions are not available for
1127 importing. The ones that are importable as specified.
1131 =item B<find_type_constraint($type_name)>
1133 This function can be used to locate the L<Moose::Meta::TypeConstraint>
1134 object for a named type.
1136 This function is importable.
1138 =item B<register_type_constraint($type_object)>
1140 This function will register a L<Moose::Meta::TypeConstraint> with the
1141 global type registry.
1143 This function is importable.
1145 =item B<normalize_type_constraint_name($type_constraint_name)>
1147 This method takes a type constraint name and returns the normalized
1148 form. This removes any whitespace in the string.
1150 =item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
1152 This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1153 or a list of names. It returns a new
1154 L<Moose::Meta::TypeConstraint::Union> object.
1156 =item B<create_parameterized_type_constraint($type_name)>
1158 Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1159 this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1160 object. The C<BaseType> must exist already exist as a parameterizable
1163 =item B<create_class_type_constraint($class, $options)>
1165 Given a class name this function will create a new
1166 L<Moose::Meta::TypeConstraint::Class> object for that class name.
1168 The C<$options> is a hash reference that will be passed to the
1169 L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
1171 =item B<create_role_type_constraint($role, $options)>
1173 Given a role name this function will create a new
1174 L<Moose::Meta::TypeConstraint::Role> object for that role name.
1176 The C<$options> is a hash reference that will be passed to the
1177 L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
1179 =item B<create_enum_type_constraint($name, $values)>
1181 Given a enum name this function will create a new
1182 L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1184 =item B<find_or_parse_type_constraint($type_name)>
1186 Given a type name, this first attempts to find a matching constraint
1187 in the global registry.
1189 If the type name is a union or parameterized type, it will create a
1190 new object of the appropriate, but if given a "regular" type that does
1191 not yet exist, it simply returns false.
1193 When given a union or parameterized type, the member or base type must
1196 If it creates a new union or parameterized type, it will add it to the
1199 =item B<find_or_create_isa_type_constraint($type_name)>
1201 =item B<find_or_create_does_type_constraint($type_name)>
1203 These functions will first call C<find_or_parse_type_constraint>. If
1204 that function does not return a type, a new anonymous type object will
1207 The C<isa> variant will use C<create_class_type_constraint> and the
1208 C<does> variant will use C<create_role_type_constraint>.
1210 =item B<get_type_constraint_registry>
1212 Returns the L<Moose::Meta::TypeConstraint::Registry> object which
1213 keeps track of all type constraints.
1215 =item B<list_all_type_constraints>
1217 This will return a list of type constraint names in the global
1218 registry. You can then fetch the actual type object using
1219 C<find_type_constraint($type_name)>.
1221 =item B<list_all_builtin_type_constraints>
1223 This will return a list of builtin type constraints, meaning those
1224 which are defined in this module. See the L<Default Type Constraints>
1225 section for a complete list.
1227 =item B<export_type_constraints_as_functions>
1229 This will export all the current type constraints as functions into
1230 the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1231 mostly used for testing, but it might prove useful to others.
1233 =item B<get_all_parameterizable_types>
1235 This returns all the parameterizable types that have been registered,
1236 as a list of type objects.
1238 =item B<add_parameterizable_type($type)>
1240 Adds C<$type> to the list of parameterizable types
1246 All complex software has bugs lurking in it, and this module is no
1247 exception. If you find a bug please either email me, or add the bug
1252 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1254 =head1 COPYRIGHT AND LICENSE
1256 Copyright 2006-2009 by Infinity Interactive, Inc.
1258 L<http://www.iinteractive.com>
1260 This library is free software; you can redistribute it and/or modify
1261 it under the same terms as Perl itself.