2 package Moose::Util::TypeConstraints;
5 use List::MoreUtils qw( all any );
6 use Scalar::Util qw( blessed reftype );
9 our $AUTHORITY = 'cpan:STEVAN';
11 ## --------------------------------------------------------
12 # Prototyped subs must be predeclared because we have a
13 # circular dependency with Moose::Meta::Attribute et. al.
14 # so in case of us being use'd first the predeclaration
15 # ensures the prototypes are in scope when consumers are
24 ## --------------------------------------------------------
26 use Moose::Deprecated;
27 use Moose::Meta::TypeConstraint;
28 use Moose::Meta::TypeConstraint::Union;
29 use Moose::Meta::TypeConstraint::Parameterized;
30 use Moose::Meta::TypeConstraint::Parameterizable;
31 use Moose::Meta::TypeConstraint::Class;
32 use Moose::Meta::TypeConstraint::Role;
33 use Moose::Meta::TypeConstraint::Enum;
34 use Moose::Meta::TypeConstraint::DuckType;
35 use Moose::Meta::TypeCoercion;
36 use Moose::Meta::TypeCoercion::Union;
37 use Moose::Meta::TypeConstraint::Registry;
38 use Moose::Util::TypeConstraints::OptimizedConstraints;
40 Moose::Exporter->setup_import_methods(
43 type subtype class_type role_type maybe_type duck_type
44 as where message optimize_as
48 register_type_constraint
53 ## --------------------------------------------------------
54 ## type registry and some useful functions for it
55 ## --------------------------------------------------------
57 my $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
59 sub get_type_constraint_registry {$REGISTRY}
60 sub list_all_type_constraints { keys %{ $REGISTRY->type_constraints } }
62 sub export_type_constraints_as_functions {
65 foreach my $constraint ( keys %{ $REGISTRY->type_constraints } ) {
66 my $tc = $REGISTRY->get_type_constraint($constraint)
67 ->_compiled_type_constraint;
68 *{"${pkg}::${constraint}"}
69 = sub { $tc->( $_[0] ) ? 1 : undef }; # the undef is for compat
73 sub create_type_constraint_union {
74 my @type_constraint_names;
76 if ( scalar @_ == 1 && _detect_type_constraint_union( $_[0] ) ) {
77 @type_constraint_names = _parse_type_constraint_union( $_[0] );
80 @type_constraint_names = @_;
83 ( scalar @type_constraint_names >= 2 )
84 || __PACKAGE__->_throw_error(
85 "You must pass in at least 2 type names to make a union");
87 my @type_constraints = map {
88 find_or_parse_type_constraint($_)
89 || __PACKAGE__->_throw_error(
90 "Could not locate type constraint ($_) for the union");
91 } @type_constraint_names;
93 return Moose::Meta::TypeConstraint::Union->new(
94 type_constraints => \@type_constraints );
97 sub create_parameterized_type_constraint {
98 my $type_constraint_name = shift;
99 my ( $base_type, $type_parameter )
100 = _parse_parameterized_type_constraint($type_constraint_name);
102 ( defined $base_type && defined $type_parameter )
103 || __PACKAGE__->_throw_error(
104 "Could not parse type name ($type_constraint_name) correctly");
106 if ( $REGISTRY->has_type_constraint($base_type) ) {
107 my $base_type_tc = $REGISTRY->get_type_constraint($base_type);
108 return _create_parameterized_type_constraint(
114 __PACKAGE__->_throw_error(
115 "Could not locate the base type ($base_type)");
119 sub _create_parameterized_type_constraint {
120 my ( $base_type_tc, $type_parameter ) = @_;
121 if ( $base_type_tc->can('parameterize') ) {
122 return $base_type_tc->parameterize($type_parameter);
125 return Moose::Meta::TypeConstraint::Parameterized->new(
126 name => $base_type_tc->name . '[' . $type_parameter . ']',
127 parent => $base_type_tc,
129 find_or_create_isa_type_constraint($type_parameter),
134 #should we also support optimized checks?
135 sub create_class_type_constraint {
136 my ( $class, $options ) = @_;
138 # too early for this check
139 #find_type_constraint("ClassName")->check($class)
140 # || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
148 $options{name} ||= "__ANON__";
150 Moose::Meta::TypeConstraint::Class->new(%options);
153 sub create_role_type_constraint {
154 my ( $role, $options ) = @_;
156 # too early for this check
157 #find_type_constraint("ClassName")->check($class)
158 # || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
166 $options{name} ||= "__ANON__";
168 Moose::Meta::TypeConstraint::Role->new(%options);
171 sub find_or_create_type_constraint {
172 my ( $type_constraint_name, $options_for_anon_type ) = @_;
175 = find_or_parse_type_constraint($type_constraint_name) ) {
178 elsif ( defined $options_for_anon_type ) {
181 # if there is no $options_for_anon_type
182 # specified, then we assume they don't
183 # want to create one, and return nothing.
185 # otherwise assume that we should create
186 # an ANON type with the $options_for_anon_type
187 # options which can be passed in. It should
188 # be noted that these don't get registered
189 # so we need to return it.
191 return Moose::Meta::TypeConstraint->new(
193 %{$options_for_anon_type}
200 sub find_or_create_isa_type_constraint {
201 my $type_constraint_name = shift;
202 find_or_parse_type_constraint($type_constraint_name)
203 || create_class_type_constraint($type_constraint_name);
206 sub find_or_create_does_type_constraint {
207 my $type_constraint_name = shift;
208 find_or_parse_type_constraint($type_constraint_name)
209 || create_role_type_constraint($type_constraint_name);
212 sub find_or_parse_type_constraint {
213 my $type_constraint_name = normalize_type_constraint_name(shift);
216 if ( $constraint = find_type_constraint($type_constraint_name) ) {
219 elsif ( _detect_type_constraint_union($type_constraint_name) ) {
220 $constraint = create_type_constraint_union($type_constraint_name);
222 elsif ( _detect_parameterized_type_constraint($type_constraint_name) ) {
224 = create_parameterized_type_constraint($type_constraint_name);
230 $REGISTRY->add_type_constraint($constraint);
234 sub normalize_type_constraint_name {
235 my $type_constraint_name = shift;
236 $type_constraint_name =~ s/\s//g;
237 return $type_constraint_name;
243 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
244 Carp::confess($error);
247 ## --------------------------------------------------------
248 ## exported functions ...
249 ## --------------------------------------------------------
251 sub find_type_constraint {
254 if ( blessed $type and $type->isa("Moose::Meta::TypeConstraint") ) {
258 return unless $REGISTRY->has_type_constraint($type);
259 return $REGISTRY->get_type_constraint($type);
263 sub register_type_constraint {
264 my $constraint = shift;
265 __PACKAGE__->_throw_error("can't register an unnamed type constraint")
266 unless defined $constraint->name;
267 $REGISTRY->add_type_constraint($constraint);
275 # back-compat version, called without sugar
276 if ( !any { ( reftype($_) || '' ) eq 'HASH' } @_ ) {
277 Moose::Deprecated::deprecated(
278 feature => 'type without sugar',
280 'Calling type() with a simple list of parameters is deprecated'
283 return _create_type_constraint( $_[0], undef, $_[1] );
288 my %p = map { %{$_} } @_;
290 return _create_type_constraint(
291 $name, undef, $p{where}, $p{message},
298 # crazy back-compat code for being called without sugar ...
300 # subtype 'Parent', sub { where };
301 if ( scalar @_ == 2 && ( reftype( $_[1] ) || '' ) eq 'CODE' ) {
302 Moose::Deprecated::deprecated(
303 feature => 'subtype without sugar',
305 'Calling subtype() with a simple list of parameters is deprecated'
308 return _create_type_constraint( undef, @_ );
311 # subtype 'Parent', sub { where }, sub { message };
312 # subtype 'Parent', sub { where }, sub { message }, sub { optimized };
313 if ( scalar @_ >= 3 && all { ( reftype($_) || '' ) eq 'CODE' }
315 Moose::Deprecated::deprecated(
316 feature => 'subtype without sugar',
318 'Calling subtype() with a simple list of parameters is deprecated'
321 return _create_type_constraint( undef, @_ );
324 # subtype 'Name', 'Parent', ...
325 if ( scalar @_ >= 2 && all { !ref } @_[ 0, 1 ] ) {
326 Moose::Deprecated::deprecated(
327 feature => 'subtype without sugar',
329 'Calling subtype() with a simple list of parameters is deprecated'
332 return _create_type_constraint(@_);
335 if ( @_ == 1 && !ref $_[0] ) {
336 __PACKAGE__->_throw_error(
337 'A subtype cannot consist solely of a name, it must have a parent'
341 # The blessed check is mostly to accommodate MooseX::Types, which
342 # uses an object which overloads stringification as a type name.
343 my $name = ref $_[0] && !blessed $_[0] ? undef : shift;
345 my %p = map { %{$_} } @_;
347 # subtype Str => where { ... };
348 if ( !exists $p{as} ) {
353 return _create_type_constraint(
354 $name, $p{as}, $p{where}, $p{message},
360 register_type_constraint(
361 create_class_type_constraint(
363 ( defined( $_[1] ) ? $_[1] : () ),
368 sub role_type ($;$) {
369 register_type_constraint(
370 create_role_type_constraint(
372 ( defined( $_[1] ) ? $_[1] : () ),
378 my ($type_parameter) = @_;
380 register_type_constraint(
381 $REGISTRY->get_type_constraint('Maybe')->parameterize($type_parameter)
386 my ( $type_name, @methods ) = @_;
387 if ( ref $type_name eq 'ARRAY' && !@methods ) {
388 @methods = @$type_name;
391 if ( @methods == 1 && ref $methods[0] eq 'ARRAY' ) {
392 @methods = @{ $methods[0] };
395 register_type_constraint(
396 create_duck_type_constraint(
404 my ( $type_name, @coercion_map ) = @_;
405 _install_type_coercions( $type_name, \@coercion_map );
408 # The trick of returning @_ lets us avoid having to specify a
409 # prototype. Perl will parse this:
417 # subtype( 'Foo', as( 'Str', where { ... } ) );
419 # If as() returns all it's extra arguments, this just works, and
420 # preserves backwards compatibility.
421 sub as { { as => shift }, @_ }
422 sub where (&) { { where => $_[0] } }
423 sub message (&) { { message => $_[0] } }
424 sub optimize_as (&) { { optimize_as => $_[0] } }
427 sub via (&) { $_[0] }
430 my ( $type_name, @values ) = @_;
433 # if only an array-ref is passed then
434 # you get an anon-enum
436 if ( ref $type_name eq 'ARRAY' ) {
438 || __PACKAGE__->_throw_error("enum called with an array reference and additional arguments. Did you mean to parenthesize the enum call's parameters?");
440 @values = @$type_name;
443 if ( @values == 1 && ref $values[0] eq 'ARRAY' ) {
444 @values = @{ $values[0] };
447 register_type_constraint(
448 create_enum_type_constraint(
455 sub create_enum_type_constraint {
456 my ( $type_name, $values ) = @_;
458 Moose::Meta::TypeConstraint::Enum->new(
459 name => $type_name || '__ANON__',
464 sub create_duck_type_constraint {
465 my ( $type_name, $methods ) = @_;
467 Moose::Meta::TypeConstraint::DuckType->new(
468 name => $type_name || '__ANON__',
474 my ($to_match, @cases) = @_;
476 if (@cases % 2 != 0) {
477 $default = pop @cases;
478 (ref $default eq 'CODE')
479 || __PACKAGE__->_throw_error("Default case must be a CODE ref, not $default");
482 my ($type, $action) = splice @cases, 0, 2;
484 unless (blessed $type && $type->isa('Moose::Meta::TypeConstraint')) {
485 $type = find_or_parse_type_constraint($type)
486 || __PACKAGE__->_throw_error("Cannot find or parse the type '$type'")
489 (ref $action eq 'CODE')
490 || __PACKAGE__->_throw_error("Match action must be a CODE ref, not $action");
492 if ($type->check($to_match)) {
493 local $_ = $to_match;
494 return $action->($to_match);
498 || __PACKAGE__->_throw_error("No cases matched for $to_match");
500 local $_ = $to_match;
501 return $default->($to_match);
506 ## --------------------------------------------------------
507 ## desugaring functions ...
508 ## --------------------------------------------------------
510 sub _create_type_constraint ($$$;$$) {
515 my $optimized = shift;
517 my $pkg_defined_in = scalar( caller(1) );
519 if ( defined $name ) {
520 my $type = $REGISTRY->get_type_constraint($name);
522 ( $type->_package_defined_in eq $pkg_defined_in )
524 "The type constraint '$name' has already been created in "
525 . $type->_package_defined_in
526 . " and cannot be created again in "
530 $name =~ /^[\w:\.]+$/
531 or die qq{$name contains invalid characters for a type name.}
532 . qq{ Names can contain alphanumeric character, ":", and "."\n};
537 package_defined_in => $pkg_defined_in,
539 ( $check ? ( constraint => $check ) : () ),
540 ( $message ? ( message => $message ) : () ),
541 ( $optimized ? ( optimized => $optimized ) : () ),
550 : find_or_create_isa_type_constraint($parent)
552 $constraint = $parent->create_child_type(%opts);
555 $constraint = Moose::Meta::TypeConstraint->new(%opts);
558 $REGISTRY->add_type_constraint($constraint)
564 sub _install_type_coercions ($$) {
565 my ( $type_name, $coercion_map ) = @_;
566 my $type = find_type_constraint($type_name);
568 || __PACKAGE__->_throw_error(
569 "Cannot find type '$type_name', perhaps you forgot to load it");
570 if ( $type->has_coercion ) {
571 $type->coercion->add_type_coercions(@$coercion_map);
574 my $type_coercion = Moose::Meta::TypeCoercion->new(
575 type_coercion_map => $coercion_map,
576 type_constraint => $type
578 $type->coercion($type_coercion);
582 ## --------------------------------------------------------
583 ## type notation parsing ...
584 ## --------------------------------------------------------
588 # All I have to say is mugwump++ cause I know
589 # do not even have enough regexp-fu to be able
590 # to have written this (I can only barely
591 # understand it as it is)
596 my $valid_chars = qr{[\w:\.]};
597 my $type_atom = qr{ (?>$valid_chars+) }x;
598 my $ws = qr{ (?>\s*) }x;
599 my $op_union = qr{ $ws \| $ws }x;
601 my ($type, $type_capture_parts, $type_with_parameter, $union, $any);
602 if (Class::MOP::IS_RUNNING_ON_5_10) {
604 = q{ (?&type_atom) (?: \[ (?&ws) (?&any) (?&ws) \] )? };
605 my $type_capture_parts_pattern
606 = q{ ((?&type_atom)) (?: \[ (?&ws) ((?&any)) (?&ws) \] )? };
607 my $type_with_parameter_pattern
608 = q{ (?&type_atom) \[ (?&ws) (?&any) (?&ws) \] };
610 = q{ (?&type) (?> (?: (?&op_union) (?&type) )+ ) };
612 = q{ (?&type) | (?&union) };
614 my $defines = qr{(?(DEFINE)
615 (?<valid_chars> $valid_chars)
616 (?<type_atom> $type_atom)
618 (?<op_union> $op_union)
619 (?<type> $type_pattern)
620 (?<type_capture_parts> $type_capture_parts_pattern)
621 (?<type_with_parameter> $type_with_parameter_pattern)
622 (?<union> $union_pattern)
623 (?<any> $any_pattern)
626 $type = qr{ $type_pattern $defines }x;
627 $type_capture_parts = qr{ $type_capture_parts_pattern $defines }x;
628 $type_with_parameter = qr{ $type_with_parameter_pattern $defines }x;
629 $union = qr{ $union_pattern $defines }x;
630 $any = qr{ $any_pattern $defines }x;
634 = qr{ $type_atom (?: \[ $ws (??{$any}) $ws \] )? }x;
636 = qr{ ($type_atom) (?: \[ $ws ((??{$any})) $ws \] )? }x;
638 = qr{ $type_atom \[ $ws (??{$any}) $ws \] }x;
640 = qr{ $type (?> (?: $op_union $type )+ ) }x;
642 = qr{ $type | $union }x;
646 sub _parse_parameterized_type_constraint {
647 { no warnings 'void'; $any; } # force capture of interpolated lexical
648 $_[0] =~ m{ $type_capture_parts }x;
652 sub _detect_parameterized_type_constraint {
653 { no warnings 'void'; $any; } # force capture of interpolated lexical
654 $_[0] =~ m{ ^ $type_with_parameter $ }x;
657 sub _parse_type_constraint_union {
658 { no warnings 'void'; $any; } # force capture of interpolated lexical
661 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
664 ( pos($given) eq length($given) )
665 || __PACKAGE__->_throw_error( "'$given' didn't parse (parse-pos="
673 sub _detect_type_constraint_union {
674 { no warnings 'void'; $any; } # force capture of interpolated lexical
675 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
679 ## --------------------------------------------------------
680 # define some basic built-in types
681 ## --------------------------------------------------------
683 # By making these classes immutable before creating all the types we
684 # below, we avoid repeatedly calling the slow MOP-based accessors.
686 inline_constructor => 1,
687 constructor_name => "_new",
689 # these are Class::MOP accessors, so they need inlining
690 inline_accessors => 1
691 ) for grep { $_->is_mutable }
692 map { Class::MOP::class_of($_) }
694 Moose::Meta::TypeConstraint
695 Moose::Meta::TypeConstraint::Union
696 Moose::Meta::TypeConstraint::Parameterized
697 Moose::Meta::TypeConstraint::Parameterizable
698 Moose::Meta::TypeConstraint::Class
699 Moose::Meta::TypeConstraint::Role
700 Moose::Meta::TypeConstraint::Enum
701 Moose::Meta::TypeConstraint::DuckType
702 Moose::Meta::TypeConstraint::Registry
705 type 'Any' => where {1}; # meta-type including all
706 subtype 'Item' => as 'Any'; # base-type
708 subtype 'Undef' => as 'Item' => where { !defined($_) };
709 subtype 'Defined' => as 'Item' => where { defined($_) };
711 subtype 'Bool' => as 'Item' =>
712 where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
714 subtype 'Value' => as 'Defined' => where { !ref($_) } =>
715 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
717 subtype 'Ref' => as 'Defined' => where { ref($_) } =>
718 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
720 subtype 'Str' => as 'Value' => where { ref(\$_) eq 'SCALAR' } =>
721 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
723 subtype 'Num' => as 'Str' =>
724 where { Scalar::Util::looks_like_number($_) } =>
725 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
727 subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } =>
728 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
730 subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
731 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
732 subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } =>
734 \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
735 subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
736 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
739 # scalar filehandles are GLOB refs,
740 # but a GLOB ref is not always a filehandle
741 subtype 'FileHandle' => as 'GlobRef' => where {
742 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
744 \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
747 # blessed(qr/.../) returns true,.. how odd
748 subtype 'Object' => as 'Ref' =>
749 where { blessed($_) && blessed($_) ne 'Regexp' } =>
750 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
752 # This type is deprecated.
753 subtype 'Role' => as 'Object' => where { $_->can('does') } =>
754 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
756 my $_class_name_checker = sub { };
758 subtype 'ClassName' => as 'Str' =>
759 where { Class::MOP::is_class_loaded($_) } => optimize_as
760 \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
762 subtype 'RoleName' => as 'ClassName' => where {
763 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
765 \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
767 ## --------------------------------------------------------
768 # parameterizable types ...
770 $REGISTRY->add_type_constraint(
771 Moose::Meta::TypeConstraint::Parameterizable->new(
773 package_defined_in => __PACKAGE__,
774 parent => find_type_constraint('Ref'),
775 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
777 \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef,
778 constraint_generator => sub {
779 my $type_parameter = shift;
780 my $check = $type_parameter->_compiled_type_constraint;
782 return $check->(${ $_ });
788 $REGISTRY->add_type_constraint(
789 Moose::Meta::TypeConstraint::Parameterizable->new(
791 package_defined_in => __PACKAGE__,
792 parent => find_type_constraint('Ref'),
793 constraint => sub { ref($_) eq 'ARRAY' },
795 \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
796 constraint_generator => sub {
797 my $type_parameter = shift;
798 my $check = $type_parameter->_compiled_type_constraint;
800 foreach my $x (@$_) {
801 ( $check->($x) ) || return;
809 $REGISTRY->add_type_constraint(
810 Moose::Meta::TypeConstraint::Parameterizable->new(
812 package_defined_in => __PACKAGE__,
813 parent => find_type_constraint('Ref'),
814 constraint => sub { ref($_) eq 'HASH' },
816 \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
817 constraint_generator => sub {
818 my $type_parameter = shift;
819 my $check = $type_parameter->_compiled_type_constraint;
821 foreach my $x ( values %$_ ) {
822 ( $check->($x) ) || return;
830 $REGISTRY->add_type_constraint(
831 Moose::Meta::TypeConstraint::Parameterizable->new(
833 package_defined_in => __PACKAGE__,
834 parent => find_type_constraint('Item'),
835 constraint => sub {1},
836 constraint_generator => sub {
837 my $type_parameter = shift;
838 my $check = $type_parameter->_compiled_type_constraint;
840 return 1 if not( defined($_) ) || $check->($_);
847 my @PARAMETERIZABLE_TYPES
848 = map { $REGISTRY->get_type_constraint($_) } qw[ScalarRef ArrayRef HashRef Maybe];
850 sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
852 sub add_parameterizable_type {
855 && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
856 || __PACKAGE__->_throw_error(
857 "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
859 push @PARAMETERIZABLE_TYPES => $type;
862 ## --------------------------------------------------------
863 # end of built-in types ...
864 ## --------------------------------------------------------
867 my @BUILTINS = list_all_type_constraints();
868 sub list_all_builtin_type_constraints {@BUILTINS}
875 goto &Moose::throw_error;
880 # ABSTRACT: Type constraint system for Moose
888 use Moose::Util::TypeConstraints;
894 subtype 'NaturalLessThanTen'
897 => message { "This number ($_) is not less than ten!" };
903 enum 'RGBColors' => qw(red green blue);
905 no Moose::Util::TypeConstraints;
909 This module provides Moose with the ability to create custom type
910 constraints to be used in attribute definition.
912 =head2 Important Caveat
914 This is B<NOT> a type system for Perl 5. These are type constraints,
915 and they are not used by Moose unless you tell it to. No type
916 inference is performed, expressions are not typed, etc. etc. etc.
918 A type constraint is at heart a small "check if a value is valid"
919 function. A constraint can be associated with an attribute. This
920 simplifies parameter validation, and makes your code clearer to read,
921 because you can refer to constraints by name.
923 =head2 Slightly Less Important Caveat
925 It is B<always> a good idea to quote your type names.
927 This prevents Perl from trying to execute the call as an indirect
928 object call. This can be an issue when you have a subtype with the
929 same name as a valid class.
933 subtype DateTime => as Object => where { $_->isa('DateTime') };
935 will I<just work>, while this:
938 subtype DateTime => as Object => where { $_->isa('DateTime') };
940 will fail silently and cause many headaches. The simple way to solve
941 this, as well as future proof your subtypes from classes which have
942 yet to have been created, is to quote the type name:
945 subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
947 =head2 Default Type Constraints
949 This module also provides a simple hierarchy for Perl 5 types, here is
950 that hierarchy represented visually.
974 B<NOTE:> Any type followed by a type parameter C<[`a]> can be
975 parameterized, this means you can say:
977 ArrayRef[Int] # an array of integers
978 HashRef[CodeRef] # a hash of str to CODE ref mappings
979 ScalarRef[Int] # a reference to an integer
980 Maybe[Str] # value may be a string, may be undefined
982 If Moose finds a name in brackets that it does not recognize as an
983 existing type, it assumes that this is a class name, for example
984 C<ArrayRef[DateTime]>.
986 B<NOTE:> Unless you parameterize a type, then it is invalid to include
987 the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
988 name, I<not> as a parameterization of C<ArrayRef>.
990 B<NOTE:> The C<Undef> type constraint for the most part works
991 correctly now, but edge cases may still exist, please use it
994 B<NOTE:> The C<ClassName> type constraint does a complex package
995 existence check. This means that your class B<must> be loaded for this
996 type constraint to pass.
998 B<NOTE:> The C<RoleName> constraint checks a string is a I<package
999 name> which is a role, like C<'MyApp::Role::Comparable'>.
1001 =head2 Type Constraint Naming
1003 Type name declared via this module can only contain alphanumeric
1004 characters, colons (:), and periods (.).
1006 Since the types created by this module are global, it is suggested
1007 that you namespace your types just as you would namespace your
1008 modules. So instead of creating a I<Color> type for your
1009 B<My::Graphics> module, you would call the type
1010 I<My::Graphics::Types::Color> instead.
1012 =head2 Use with Other Constraint Modules
1014 This module can play nicely with other constraint modules with some
1015 slight tweaking. The C<where> clause in types is expected to be a
1016 C<CODE> reference which checks it's first argument and returns a
1017 boolean. Since most constraint modules work in a similar way, it
1018 should be simple to adapt them to work with Moose.
1020 For instance, this is how you could use it with
1021 L<Declare::Constraints::Simple> to declare a completely new type.
1023 type 'HashOfArrayOfObjects',
1027 -values => IsArrayRef(IsObject)
1031 For more examples see the F<t/200_examples/004_example_w_DCS.t> test
1034 Here is an example of using L<Test::Deep> and it's non-test
1035 related C<eq_deeply> function.
1037 type 'ArrayOfHashOfBarsAndRandomNumbers'
1040 array_each(subhashof({
1042 random_number => ignore()
1046 For a complete example see the
1047 F<t/200_examples/005_example_w_TestDeep.t> test file.
1051 =head2 Type Constraint Constructors
1053 The following functions are used to create type constraints. They
1054 will also register the type constraints your create in a global
1055 registry that is used to look types up by name.
1057 See the L</SYNOPSIS> for an example of how to use these.
1061 =item B<< subtype 'Name' => as 'Parent' => where { } ... >>
1063 This creates a named subtype.
1065 If you provide a parent that Moose does not recognize, it will
1066 automatically create a new class type constraint for this name.
1068 When creating a named type, the C<subtype> function should either be
1069 called with the sugar helpers (C<where>, C<message>, etc), or with a
1070 name and a hashref of parameters:
1072 subtype( 'Foo', { where => ..., message => ... } );
1074 The valid hashref keys are C<as> (the parent), C<where>, C<message>,
1077 =item B<< subtype as 'Parent' => where { } ... >>
1079 This creates an unnamed subtype and will return the type
1080 constraint meta-object, which will be an instance of
1081 L<Moose::Meta::TypeConstraint>.
1083 When creating an anonymous type, the C<subtype> function should either
1084 be called with the sugar helpers (C<where>, C<message>, etc), or with
1085 just a hashref of parameters:
1087 subtype( { where => ..., message => ... } );
1089 =item B<class_type ($class, ?$options)>
1091 Creates a new subtype of C<Object> with the name C<$class> and the
1092 metaclass L<Moose::Meta::TypeConstraint::Class>.
1094 =item B<role_type ($role, ?$options)>
1096 Creates a C<Role> type constraint with the name C<$role> and the
1097 metaclass L<Moose::Meta::TypeConstraint::Role>.
1099 =item B<maybe_type ($type)>
1101 Creates a type constraint for either C<undef> or something of the
1104 =item B<duck_type ($name, \@methods)>
1106 This will create a subtype of Object and test to make sure the value
1107 C<can()> do the methods in C<\@methods>.
1109 This is intended as an easy way to accept non-Moose objects that
1110 provide a certain interface. If you're using Moose classes, we
1111 recommend that you use a C<requires>-only Role instead.
1113 =item B<duck_type (\@methods)>
1115 If passed an ARRAY reference as the only parameter instead of the
1116 C<$name>, C<\@methods> pair, this will create an unnamed duck type.
1117 This can be used in an attribute definition like so:
1121 isa => duck_type( [qw( get_set )] ),
1124 =item B<enum ($name, \@values)>
1126 This will create a basic subtype for a given set of strings.
1127 The resulting constraint will be a subtype of C<Str> and
1128 will match any of the items in C<\@values>. It is case sensitive.
1129 See the L</SYNOPSIS> for a simple example.
1131 B<NOTE:> This is not a true proper enum type, it is simply
1132 a convenient constraint builder.
1134 =item B<enum (\@values)>
1136 If passed an ARRAY reference as the only parameter instead of the
1137 C<$name>, C<\@values> pair, this will create an unnamed enum. This
1138 can then be used in an attribute definition like so:
1140 has 'sort_order' => (
1142 isa => enum([qw[ ascending descending ]]),
1145 =item B<as 'Parent'>
1147 This is just sugar for the type constraint construction syntax.
1149 It takes a single argument, which is the name of a parent type.
1151 =item B<where { ... }>
1153 This is just sugar for the type constraint construction syntax.
1155 It takes a subroutine reference as an argument. When the type
1156 constraint is tested, the reference is run with the value to be tested
1157 in C<$_>. This reference should return true or false to indicate
1158 whether or not the constraint check passed.
1160 =item B<message { ... }>
1162 This is just sugar for the type constraint construction syntax.
1164 It takes a subroutine reference as an argument. When the type
1165 constraint fails, then the code block is run with the value provided
1166 in C<$_>. This reference should return a string, which will be used in
1167 the text of the exception thrown.
1169 =item B<optimize_as { ... }>
1171 This can be used to define a "hand optimized" version of your
1172 type constraint which can be used to avoid traversing a subtype
1173 constraint hierarchy.
1175 B<NOTE:> You should only use this if you know what you are doing,
1176 all the built in types use this, so your subtypes (assuming they
1177 are shallow) will not likely need to use this.
1179 =item B<< type 'Name' => where { } ... >>
1181 This creates a base type, which has no parent.
1183 The C<type> function should either be called with the sugar helpers
1184 (C<where>, C<message>, etc), or with a name and a hashref of
1187 type( 'Foo', { where => ..., message => ... } );
1189 The valid hashref keys are C<where>, C<message>, and C<optimize_as>.
1193 =head2 Type Constraint Utilities
1197 =item B<< match_on_type $value => ( $type => \&action, ... ?\&default ) >>
1199 This is a utility function for doing simple type based dispatching similar to
1200 match/case in OCaml and case/of in Haskell. It is not as featureful as those
1201 languages, nor does not it support any kind of automatic destructuring
1202 bind. Here is a simple Perl pretty printer dispatching over the core Moose
1207 match_on_type $x => (
1212 join ", " => map { $_ . ' => ' . ppprint( $hash->{$_} ) }
1218 '[ ' . ( join ", " => map { ppprint($_) } @$array ) . ' ]';
1220 CodeRef => sub {'sub { ... }'},
1221 RegexpRef => sub { 'qr/' . $_ . '/' },
1222 GlobRef => sub { '*' . B::svref_2object($_)->NAME },
1223 Object => sub { $_->can('to_string') ? $_->to_string : $_ },
1224 ScalarRef => sub { '\\' . ppprint( ${$_} ) },
1226 Str => sub { '"' . $_ . '"' },
1227 Undef => sub {'undef'},
1228 => sub { die "I don't know what $_ is" }
1232 Or a simple JSON serializer:
1236 match_on_type $x => (
1242 map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
1248 '[ ' . ( join ", " => map { to_json($_) } @$array ) . ' ]';
1251 Str => sub { '"' . $_ . '"' },
1252 Undef => sub {'null'},
1253 => sub { die "$_ is not acceptable json type" }
1257 The matcher is done by mapping a C<$type> to an C<\&action>. The C<$type> can
1258 be either a string type or a L<Moose::Meta::TypeConstraint> object, and
1259 C<\&action> is a subroutine reference. This function will dispatch on the
1260 first match for C<$value>. It is possible to have a catch-all by providing an
1261 additional subroutine reference as the final argument to C<match_on_type>.
1265 =head2 Type Coercion Constructors
1267 You can define coercions for type constraints, which allow you to
1268 automatically transform values to something valid for the type
1269 constraint. If you ask your accessor to coerce, then Moose will run
1270 the type-coercion code first, followed by the type constraint
1271 check. This feature should be used carefully as it is very powerful
1272 and could easily take off a limb if you are not careful.
1274 See the L</SYNOPSIS> for an example of how to use these.
1278 =item B<< coerce 'Name' => from 'OtherName' => via { ... } >>
1280 This defines a coercion from one type to another. The C<Name> argument
1281 is the type you are coercing I<to>.
1283 To define multiple coercions, supply more sets of from/via pairs:
1286 from 'OtherName' => via { ... },
1287 from 'ThirdName' => via { ... };
1289 =item B<from 'OtherName'>
1291 This is just sugar for the type coercion construction syntax.
1293 It takes a single type name (or type object), which is the type being
1296 =item B<via { ... }>
1298 This is just sugar for the type coercion construction syntax.
1300 It takes a subroutine reference. This reference will be called with
1301 the value to be coerced in C<$_>. It is expected to return a new value
1302 of the proper type for the coercion.
1306 =head2 Creating and Finding Type Constraints
1308 These are additional functions for creating and finding type
1309 constraints. Most of these functions are not available for
1310 importing. The ones that are importable as specified.
1314 =item B<find_type_constraint($type_name)>
1316 This function can be used to locate the L<Moose::Meta::TypeConstraint>
1317 object for a named type.
1319 This function is importable.
1321 =item B<register_type_constraint($type_object)>
1323 This function will register a L<Moose::Meta::TypeConstraint> with the
1324 global type registry.
1326 This function is importable.
1328 =item B<normalize_type_constraint_name($type_constraint_name)>
1330 This method takes a type constraint name and returns the normalized
1331 form. This removes any whitespace in the string.
1333 =item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
1335 This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1336 or a list of names. It returns a new
1337 L<Moose::Meta::TypeConstraint::Union> object.
1339 =item B<create_parameterized_type_constraint($type_name)>
1341 Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1342 this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1343 object. The C<BaseType> must exist already exist as a parameterizable
1346 =item B<create_class_type_constraint($class, $options)>
1348 Given a class name this function will create a new
1349 L<Moose::Meta::TypeConstraint::Class> object for that class name.
1351 The C<$options> is a hash reference that will be passed to the
1352 L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
1354 =item B<create_role_type_constraint($role, $options)>
1356 Given a role name this function will create a new
1357 L<Moose::Meta::TypeConstraint::Role> object for that role name.
1359 The C<$options> is a hash reference that will be passed to the
1360 L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
1362 =item B<create_enum_type_constraint($name, $values)>
1364 Given a enum name this function will create a new
1365 L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1367 =item B<create_duck_type_constraint($name, $methods)>
1369 Given a duck type name this function will create a new
1370 L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
1372 =item B<find_or_parse_type_constraint($type_name)>
1374 Given a type name, this first attempts to find a matching constraint
1375 in the global registry.
1377 If the type name is a union or parameterized type, it will create a
1378 new object of the appropriate, but if given a "regular" type that does
1379 not yet exist, it simply returns false.
1381 When given a union or parameterized type, the member or base type must
1384 If it creates a new union or parameterized type, it will add it to the
1387 =item B<find_or_create_isa_type_constraint($type_name)>
1389 =item B<find_or_create_does_type_constraint($type_name)>
1391 These functions will first call C<find_or_parse_type_constraint>. If
1392 that function does not return a type, a new anonymous type object will
1395 The C<isa> variant will use C<create_class_type_constraint> and the
1396 C<does> variant will use C<create_role_type_constraint>.
1398 =item B<get_type_constraint_registry>
1400 Returns the L<Moose::Meta::TypeConstraint::Registry> object which
1401 keeps track of all type constraints.
1403 =item B<list_all_type_constraints>
1405 This will return a list of type constraint names in the global
1406 registry. You can then fetch the actual type object using
1407 C<find_type_constraint($type_name)>.
1409 =item B<list_all_builtin_type_constraints>
1411 This will return a list of builtin type constraints, meaning those
1412 which are defined in this module. See the L<Default Type Constraints>
1413 section for a complete list.
1415 =item B<export_type_constraints_as_functions>
1417 This will export all the current type constraints as functions into
1418 the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1419 mostly used for testing, but it might prove useful to others.
1421 =item B<get_all_parameterizable_types>
1423 This returns all the parameterizable types that have been registered,
1424 as a list of type objects.
1426 =item B<add_parameterizable_type($type)>
1428 Adds C<$type> to the list of parameterizable types
1434 See L<Moose/BUGS> for details on reporting bugs.