2 package Moose::Util::TypeConstraints;
5 use List::MoreUtils qw( all any );
6 use Scalar::Util qw( blessed reftype );
9 ## --------------------------------------------------------
10 # Prototyped subs must be predeclared because we have a
11 # circular dependency with Moose::Meta::Attribute et. al.
12 # so in case of us being use'd first the predeclaration
13 # ensures the prototypes are in scope when consumers are
22 ## --------------------------------------------------------
24 use Moose::Deprecated;
25 use Moose::Meta::TypeConstraint;
26 use Moose::Meta::TypeConstraint::Union;
27 use Moose::Meta::TypeConstraint::Parameterized;
28 use Moose::Meta::TypeConstraint::Parameterizable;
29 use Moose::Meta::TypeConstraint::Class;
30 use Moose::Meta::TypeConstraint::Role;
31 use Moose::Meta::TypeConstraint::Enum;
32 use Moose::Meta::TypeConstraint::DuckType;
33 use Moose::Meta::TypeCoercion;
34 use Moose::Meta::TypeCoercion::Union;
35 use Moose::Meta::TypeConstraint::Registry;
36 use Moose::Util::TypeConstraints::OptimizedConstraints;
38 Moose::Exporter->setup_import_methods(
41 type subtype class_type role_type maybe_type duck_type
42 as where message optimize_as
46 register_type_constraint
51 ## --------------------------------------------------------
52 ## type registry and some useful functions for it
53 ## --------------------------------------------------------
55 my $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
57 sub get_type_constraint_registry {$REGISTRY}
58 sub list_all_type_constraints { keys %{ $REGISTRY->type_constraints } }
60 sub export_type_constraints_as_functions {
63 foreach my $constraint ( keys %{ $REGISTRY->type_constraints } ) {
64 my $tc = $REGISTRY->get_type_constraint($constraint)
65 ->_compiled_type_constraint;
66 *{"${pkg}::${constraint}"}
67 = sub { $tc->( $_[0] ) ? 1 : undef }; # the undef is for compat
71 sub create_type_constraint_union {
72 my @type_constraint_names;
74 if ( scalar @_ == 1 && _detect_type_constraint_union( $_[0] ) ) {
75 @type_constraint_names = _parse_type_constraint_union( $_[0] );
78 @type_constraint_names = @_;
81 ( scalar @type_constraint_names >= 2 )
82 || __PACKAGE__->_throw_error(
83 "You must pass in at least 2 type names to make a union");
85 my @type_constraints = map {
86 find_or_parse_type_constraint($_)
87 || __PACKAGE__->_throw_error(
88 "Could not locate type constraint ($_) for the union");
89 } @type_constraint_names;
91 return Moose::Meta::TypeConstraint::Union->new(
92 type_constraints => \@type_constraints );
95 sub create_parameterized_type_constraint {
96 my $type_constraint_name = shift;
97 my ( $base_type, $type_parameter )
98 = _parse_parameterized_type_constraint($type_constraint_name);
100 ( defined $base_type && defined $type_parameter )
101 || __PACKAGE__->_throw_error(
102 "Could not parse type name ($type_constraint_name) correctly");
104 if ( $REGISTRY->has_type_constraint($base_type) ) {
105 my $base_type_tc = $REGISTRY->get_type_constraint($base_type);
106 return _create_parameterized_type_constraint(
112 __PACKAGE__->_throw_error(
113 "Could not locate the base type ($base_type)");
117 sub _create_parameterized_type_constraint {
118 my ( $base_type_tc, $type_parameter ) = @_;
119 if ( $base_type_tc->can('parameterize') ) {
120 return $base_type_tc->parameterize($type_parameter);
123 return Moose::Meta::TypeConstraint::Parameterized->new(
124 name => $base_type_tc->name . '[' . $type_parameter . ']',
125 parent => $base_type_tc,
127 find_or_create_isa_type_constraint($type_parameter),
132 #should we also support optimized checks?
133 sub create_class_type_constraint {
134 my ( $class, $options ) = @_;
136 # too early for this check
137 #find_type_constraint("ClassName")->check($class)
138 # || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
146 $options{name} ||= "__ANON__";
148 Moose::Meta::TypeConstraint::Class->new(%options);
151 sub create_role_type_constraint {
152 my ( $role, $options ) = @_;
154 # too early for this check
155 #find_type_constraint("ClassName")->check($class)
156 # || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
164 $options{name} ||= "__ANON__";
166 Moose::Meta::TypeConstraint::Role->new(%options);
169 sub find_or_create_type_constraint {
170 my ( $type_constraint_name, $options_for_anon_type ) = @_;
173 = find_or_parse_type_constraint($type_constraint_name) ) {
176 elsif ( defined $options_for_anon_type ) {
179 # if there is no $options_for_anon_type
180 # specified, then we assume they don't
181 # want to create one, and return nothing.
183 # otherwise assume that we should create
184 # an ANON type with the $options_for_anon_type
185 # options which can be passed in. It should
186 # be noted that these don't get registered
187 # so we need to return it.
189 return Moose::Meta::TypeConstraint->new(
191 %{$options_for_anon_type}
198 sub find_or_create_isa_type_constraint {
199 my $type_constraint_name = shift;
200 find_or_parse_type_constraint($type_constraint_name)
201 || create_class_type_constraint($type_constraint_name);
204 sub find_or_create_does_type_constraint {
205 my $type_constraint_name = shift;
206 find_or_parse_type_constraint($type_constraint_name)
207 || create_role_type_constraint($type_constraint_name);
210 sub find_or_parse_type_constraint {
211 my $type_constraint_name = normalize_type_constraint_name(shift);
214 if ( $constraint = find_type_constraint($type_constraint_name) ) {
217 elsif ( _detect_type_constraint_union($type_constraint_name) ) {
218 $constraint = create_type_constraint_union($type_constraint_name);
220 elsif ( _detect_parameterized_type_constraint($type_constraint_name) ) {
222 = create_parameterized_type_constraint($type_constraint_name);
228 $REGISTRY->add_type_constraint($constraint);
232 sub normalize_type_constraint_name {
233 my $type_constraint_name = shift;
234 $type_constraint_name =~ s/\s//g;
235 return $type_constraint_name;
241 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
242 Carp::confess($error);
245 ## --------------------------------------------------------
246 ## exported functions ...
247 ## --------------------------------------------------------
249 sub find_type_constraint {
252 if ( blessed $type and $type->isa("Moose::Meta::TypeConstraint") ) {
256 return unless $REGISTRY->has_type_constraint($type);
257 return $REGISTRY->get_type_constraint($type);
261 sub register_type_constraint {
262 my $constraint = shift;
263 __PACKAGE__->_throw_error("can't register an unnamed type constraint")
264 unless defined $constraint->name;
265 $REGISTRY->add_type_constraint($constraint);
273 # back-compat version, called without sugar
274 if ( !any { ( reftype($_) || '' ) eq 'HASH' } @_ ) {
275 Moose::Deprecated::deprecated(
276 feature => 'type without sugar',
278 'Calling type() with a simple list of parameters is deprecated. This will be an error in Moose 2.0200.'
281 return _create_type_constraint( $_[0], undef, $_[1] );
286 my %p = map { %{$_} } @_;
288 return _create_type_constraint(
289 $name, undef, $p{where}, $p{message},
296 # crazy back-compat code for being called without sugar ...
298 # subtype 'Parent', sub { where };
299 if ( scalar @_ == 2 && ( reftype( $_[1] ) || '' ) eq 'CODE' ) {
300 Moose::Deprecated::deprecated(
301 feature => 'subtype without sugar',
303 'Calling subtype() with a simple list of parameters is deprecated. This will be an error in Moose 2.0200.'
306 return _create_type_constraint( undef, @_ );
309 # subtype 'Parent', sub { where }, sub { message };
310 # subtype 'Parent', sub { where }, sub { message }, sub { optimized };
311 if ( scalar @_ >= 3 && all { ( reftype($_) || '' ) eq 'CODE' }
313 Moose::Deprecated::deprecated(
314 feature => 'subtype without sugar',
316 'Calling subtype() with a simple list of parameters is deprecated. This will be an error in Moose 2.0200.'
319 return _create_type_constraint( undef, @_ );
322 # subtype 'Name', 'Parent', ...
323 if ( scalar @_ >= 2 && all { !ref } @_[ 0, 1 ] ) {
324 Moose::Deprecated::deprecated(
325 feature => 'subtype without sugar',
327 'Calling subtype() with a simple list of parameters is deprecated. This will be an error in Moose 2.0200.'
330 return _create_type_constraint(@_);
333 if ( @_ == 1 && !ref $_[0] ) {
334 __PACKAGE__->_throw_error(
335 'A subtype cannot consist solely of a name, it must have a parent'
339 # The blessed check is mostly to accommodate MooseX::Types, which
340 # uses an object which overloads stringification as a type name.
341 my $name = ref $_[0] && !blessed $_[0] ? undef : shift;
343 my %p = map { %{$_} } @_;
345 # subtype Str => where { ... };
346 if ( !exists $p{as} ) {
351 return _create_type_constraint(
352 $name, $p{as}, $p{where}, $p{message},
358 register_type_constraint(
359 create_class_type_constraint(
361 ( defined( $_[1] ) ? $_[1] : () ),
366 sub role_type ($;$) {
367 register_type_constraint(
368 create_role_type_constraint(
370 ( defined( $_[1] ) ? $_[1] : () ),
376 my ($type_parameter) = @_;
378 register_type_constraint(
379 $REGISTRY->get_type_constraint('Maybe')->parameterize($type_parameter)
384 my ( $type_name, @methods ) = @_;
385 if ( ref $type_name eq 'ARRAY' && !@methods ) {
386 @methods = @$type_name;
389 if ( @methods == 1 && ref $methods[0] eq 'ARRAY' ) {
390 @methods = @{ $methods[0] };
393 register_type_constraint(
394 create_duck_type_constraint(
402 my ( $type_name, @coercion_map ) = @_;
403 _install_type_coercions( $type_name, \@coercion_map );
406 # The trick of returning @_ lets us avoid having to specify a
407 # prototype. Perl will parse this:
415 # subtype( 'Foo', as( 'Str', where { ... } ) );
417 # If as() returns all it's extra arguments, this just works, and
418 # preserves backwards compatibility.
419 sub as { { as => shift }, @_ }
420 sub where (&) { { where => $_[0] } }
421 sub message (&) { { message => $_[0] } }
422 sub optimize_as (&) { { optimize_as => $_[0] } }
425 sub via (&) { $_[0] }
428 my ( $type_name, @values ) = @_;
431 # if only an array-ref is passed then
432 # you get an anon-enum
434 if ( ref $type_name eq 'ARRAY' ) {
436 || __PACKAGE__->_throw_error("enum called with an array reference and additional arguments. Did you mean to parenthesize the enum call's parameters?");
438 @values = @$type_name;
441 if ( @values == 1 && ref $values[0] eq 'ARRAY' ) {
442 @values = @{ $values[0] };
445 register_type_constraint(
446 create_enum_type_constraint(
453 sub create_enum_type_constraint {
454 my ( $type_name, $values ) = @_;
456 Moose::Meta::TypeConstraint::Enum->new(
457 name => $type_name || '__ANON__',
462 sub create_duck_type_constraint {
463 my ( $type_name, $methods ) = @_;
465 Moose::Meta::TypeConstraint::DuckType->new(
466 name => $type_name || '__ANON__',
472 my ($to_match, @cases) = @_;
474 if (@cases % 2 != 0) {
475 $default = pop @cases;
476 (ref $default eq 'CODE')
477 || __PACKAGE__->_throw_error("Default case must be a CODE ref, not $default");
480 my ($type, $action) = splice @cases, 0, 2;
482 unless (blessed $type && $type->isa('Moose::Meta::TypeConstraint')) {
483 $type = find_or_parse_type_constraint($type)
484 || __PACKAGE__->_throw_error("Cannot find or parse the type '$type'")
487 (ref $action eq 'CODE')
488 || __PACKAGE__->_throw_error("Match action must be a CODE ref, not $action");
490 if ($type->check($to_match)) {
491 local $_ = $to_match;
492 return $action->($to_match);
496 || __PACKAGE__->_throw_error("No cases matched for $to_match");
498 local $_ = $to_match;
499 return $default->($to_match);
504 ## --------------------------------------------------------
505 ## desugaring functions ...
506 ## --------------------------------------------------------
508 sub _create_type_constraint ($$$;$$) {
513 my $optimized = shift;
515 my $pkg_defined_in = scalar( caller(1) );
517 if ( defined $name ) {
518 my $type = $REGISTRY->get_type_constraint($name);
520 ( $type->_package_defined_in eq $pkg_defined_in )
522 "The type constraint '$name' has already been created in "
523 . $type->_package_defined_in
524 . " and cannot be created again in "
528 $name =~ /^[\w:\.]+$/
529 or die qq{$name contains invalid characters for a type name.}
530 . qq{ Names can contain alphanumeric character, ":", and "."\n};
535 package_defined_in => $pkg_defined_in,
537 ( $check ? ( constraint => $check ) : () ),
538 ( $message ? ( message => $message ) : () ),
539 ( $optimized ? ( optimized => $optimized ) : () ),
548 : find_or_create_isa_type_constraint($parent)
550 $constraint = $parent->create_child_type(%opts);
553 $constraint = Moose::Meta::TypeConstraint->new(%opts);
556 $REGISTRY->add_type_constraint($constraint)
562 sub _install_type_coercions ($$) {
563 my ( $type_name, $coercion_map ) = @_;
564 my $type = find_type_constraint($type_name);
566 || __PACKAGE__->_throw_error(
567 "Cannot find type '$type_name', perhaps you forgot to load it");
568 if ( $type->has_coercion ) {
569 $type->coercion->add_type_coercions(@$coercion_map);
572 my $type_coercion = Moose::Meta::TypeCoercion->new(
573 type_coercion_map => $coercion_map,
574 type_constraint => $type
576 $type->coercion($type_coercion);
580 ## --------------------------------------------------------
581 ## type notation parsing ...
582 ## --------------------------------------------------------
586 # All I have to say is mugwump++ cause I know
587 # do not even have enough regexp-fu to be able
588 # to have written this (I can only barely
589 # understand it as it is)
594 my $valid_chars = qr{[\w:\.]};
595 my $type_atom = qr{ (?>$valid_chars+) }x;
596 my $ws = qr{ (?>\s*) }x;
597 my $op_union = qr{ $ws \| $ws }x;
599 my ($type, $type_capture_parts, $type_with_parameter, $union, $any);
600 if (Class::MOP::IS_RUNNING_ON_5_10) {
602 = q{ (?&type_atom) (?: \[ (?&ws) (?&any) (?&ws) \] )? };
603 my $type_capture_parts_pattern
604 = q{ ((?&type_atom)) (?: \[ (?&ws) ((?&any)) (?&ws) \] )? };
605 my $type_with_parameter_pattern
606 = q{ (?&type_atom) \[ (?&ws) (?&any) (?&ws) \] };
608 = q{ (?&type) (?> (?: (?&op_union) (?&type) )+ ) };
610 = q{ (?&type) | (?&union) };
612 my $defines = qr{(?(DEFINE)
613 (?<valid_chars> $valid_chars)
614 (?<type_atom> $type_atom)
616 (?<op_union> $op_union)
617 (?<type> $type_pattern)
618 (?<type_capture_parts> $type_capture_parts_pattern)
619 (?<type_with_parameter> $type_with_parameter_pattern)
620 (?<union> $union_pattern)
621 (?<any> $any_pattern)
624 $type = qr{ $type_pattern $defines }x;
625 $type_capture_parts = qr{ $type_capture_parts_pattern $defines }x;
626 $type_with_parameter = qr{ $type_with_parameter_pattern $defines }x;
627 $union = qr{ $union_pattern $defines }x;
628 $any = qr{ $any_pattern $defines }x;
632 = qr{ $type_atom (?: \[ $ws (??{$any}) $ws \] )? }x;
634 = qr{ ($type_atom) (?: \[ $ws ((??{$any})) $ws \] )? }x;
636 = qr{ $type_atom \[ $ws (??{$any}) $ws \] }x;
638 = qr{ $type (?> (?: $op_union $type )+ ) }x;
640 = qr{ $type | $union }x;
644 sub _parse_parameterized_type_constraint {
645 { no warnings 'void'; $any; } # force capture of interpolated lexical
646 $_[0] =~ m{ $type_capture_parts }x;
650 sub _detect_parameterized_type_constraint {
651 { no warnings 'void'; $any; } # force capture of interpolated lexical
652 $_[0] =~ m{ ^ $type_with_parameter $ }x;
655 sub _parse_type_constraint_union {
656 { no warnings 'void'; $any; } # force capture of interpolated lexical
659 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
662 ( pos($given) eq length($given) )
663 || __PACKAGE__->_throw_error( "'$given' didn't parse (parse-pos="
671 sub _detect_type_constraint_union {
672 { no warnings 'void'; $any; } # force capture of interpolated lexical
673 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
677 ## --------------------------------------------------------
678 # define some basic built-in types
679 ## --------------------------------------------------------
681 # By making these classes immutable before creating all the types we
682 # below, we avoid repeatedly calling the slow MOP-based accessors.
684 inline_constructor => 1,
685 constructor_name => "_new",
687 # these are Class::MOP accessors, so they need inlining
688 inline_accessors => 1
689 ) for grep { $_->is_mutable }
690 map { Class::MOP::class_of($_) }
692 Moose::Meta::TypeConstraint
693 Moose::Meta::TypeConstraint::Union
694 Moose::Meta::TypeConstraint::Parameterized
695 Moose::Meta::TypeConstraint::Parameterizable
696 Moose::Meta::TypeConstraint::Class
697 Moose::Meta::TypeConstraint::Role
698 Moose::Meta::TypeConstraint::Enum
699 Moose::Meta::TypeConstraint::DuckType
700 Moose::Meta::TypeConstraint::Registry
703 type 'Any' => where {1}; # meta-type including all
704 subtype 'Item' => as 'Any'; # base-type
706 subtype 'Undef' => as 'Item' => where { !defined($_) };
707 subtype 'Defined' => as 'Item' => where { defined($_) };
709 subtype 'Bool' => as 'Item' =>
710 where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
712 subtype 'Value' => as 'Defined' => where { !ref($_) } =>
713 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
715 subtype 'Ref' => as 'Defined' => where { ref($_) } =>
716 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
718 subtype 'Str' => as 'Value' => where { ref(\$_) eq 'SCALAR' } =>
719 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
721 subtype 'Num' => as 'Str' =>
722 where { Scalar::Util::looks_like_number($_) } =>
723 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
725 subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } =>
726 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
728 subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
729 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
730 subtype 'RegexpRef' => as 'Ref' =>
731 where(\&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef) =>
732 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
733 subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
734 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
737 # scalar filehandles are GLOB refs,
738 # but a GLOB ref is not always a filehandle
739 subtype 'FileHandle' => as 'GlobRef' => where {
740 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
742 \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
744 subtype 'Object' => as 'Ref' =>
745 where { blessed($_) } =>
746 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
748 # This type is deprecated.
749 subtype 'Role' => as 'Object' => where { $_->can('does') } =>
750 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
752 my $_class_name_checker = sub { };
754 subtype 'ClassName' => as 'Str' =>
755 where { Class::MOP::is_class_loaded($_) } => optimize_as
756 \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
758 subtype 'RoleName' => as 'ClassName' => where {
759 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
761 \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
763 ## --------------------------------------------------------
764 # parameterizable types ...
766 $REGISTRY->add_type_constraint(
767 Moose::Meta::TypeConstraint::Parameterizable->new(
769 package_defined_in => __PACKAGE__,
770 parent => find_type_constraint('Ref'),
771 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
773 \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef,
774 constraint_generator => sub {
775 my $type_parameter = shift;
776 my $check = $type_parameter->_compiled_type_constraint;
778 return $check->(${ $_ });
784 $REGISTRY->add_type_constraint(
785 Moose::Meta::TypeConstraint::Parameterizable->new(
787 package_defined_in => __PACKAGE__,
788 parent => find_type_constraint('Ref'),
789 constraint => sub { ref($_) eq 'ARRAY' },
791 \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
792 constraint_generator => sub {
793 my $type_parameter = shift;
794 my $check = $type_parameter->_compiled_type_constraint;
796 foreach my $x (@$_) {
797 ( $check->($x) ) || return;
805 $REGISTRY->add_type_constraint(
806 Moose::Meta::TypeConstraint::Parameterizable->new(
808 package_defined_in => __PACKAGE__,
809 parent => find_type_constraint('Ref'),
810 constraint => sub { ref($_) eq 'HASH' },
812 \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
813 constraint_generator => sub {
814 my $type_parameter = shift;
815 my $check = $type_parameter->_compiled_type_constraint;
817 foreach my $x ( values %$_ ) {
818 ( $check->($x) ) || return;
826 $REGISTRY->add_type_constraint(
827 Moose::Meta::TypeConstraint::Parameterizable->new(
829 package_defined_in => __PACKAGE__,
830 parent => find_type_constraint('Item'),
831 constraint => sub {1},
832 constraint_generator => sub {
833 my $type_parameter = shift;
834 my $check = $type_parameter->_compiled_type_constraint;
836 return 1 if not( defined($_) ) || $check->($_);
843 my @PARAMETERIZABLE_TYPES
844 = map { $REGISTRY->get_type_constraint($_) } qw[ScalarRef ArrayRef HashRef Maybe];
846 sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
848 sub add_parameterizable_type {
851 && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
852 || __PACKAGE__->_throw_error(
853 "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
855 push @PARAMETERIZABLE_TYPES => $type;
858 ## --------------------------------------------------------
859 # end of built-in types ...
860 ## --------------------------------------------------------
863 my @BUILTINS = list_all_type_constraints();
864 sub list_all_builtin_type_constraints {@BUILTINS}
871 goto &Moose::throw_error;
876 # ABSTRACT: Type constraint system for Moose
884 use Moose::Util::TypeConstraints;
890 subtype 'NaturalLessThanTen'
893 => message { "This number ($_) is not less than ten!" };
899 enum 'RGBColors' => qw(red green blue);
901 no Moose::Util::TypeConstraints;
905 This module provides Moose with the ability to create custom type
906 constraints to be used in attribute definition.
908 =head2 Important Caveat
910 This is B<NOT> a type system for Perl 5. These are type constraints,
911 and they are not used by Moose unless you tell it to. No type
912 inference is performed, expressions are not typed, etc. etc. etc.
914 A type constraint is at heart a small "check if a value is valid"
915 function. A constraint can be associated with an attribute. This
916 simplifies parameter validation, and makes your code clearer to read,
917 because you can refer to constraints by name.
919 =head2 Slightly Less Important Caveat
921 It is B<always> a good idea to quote your type names.
923 This prevents Perl from trying to execute the call as an indirect
924 object call. This can be an issue when you have a subtype with the
925 same name as a valid class.
929 subtype DateTime => as Object => where { $_->isa('DateTime') };
931 will I<just work>, while this:
934 subtype DateTime => as Object => where { $_->isa('DateTime') };
936 will fail silently and cause many headaches. The simple way to solve
937 this, as well as future proof your subtypes from classes which have
938 yet to have been created, is to quote the type name:
941 subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
943 =head2 Default Type Constraints
945 This module also provides a simple hierarchy for Perl 5 types, here is
946 that hierarchy represented visually.
970 B<NOTE:> Any type followed by a type parameter C<[`a]> can be
971 parameterized, this means you can say:
973 ArrayRef[Int] # an array of integers
974 HashRef[CodeRef] # a hash of str to CODE ref mappings
975 ScalarRef[Int] # a reference to an integer
976 Maybe[Str] # value may be a string, may be undefined
978 If Moose finds a name in brackets that it does not recognize as an
979 existing type, it assumes that this is a class name, for example
980 C<ArrayRef[DateTime]>.
982 B<NOTE:> Unless you parameterize a type, then it is invalid to include
983 the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
984 name, I<not> as a parameterization of C<ArrayRef>.
986 B<NOTE:> The C<Undef> type constraint for the most part works
987 correctly now, but edge cases may still exist, please use it
990 B<NOTE:> The C<ClassName> type constraint does a complex package
991 existence check. This means that your class B<must> be loaded for this
992 type constraint to pass.
994 B<NOTE:> The C<RoleName> constraint checks a string is a I<package
995 name> which is a role, like C<'MyApp::Role::Comparable'>.
997 =head2 Type Constraint Naming
999 Type name declared via this module can only contain alphanumeric
1000 characters, colons (:), and periods (.).
1002 Since the types created by this module are global, it is suggested
1003 that you namespace your types just as you would namespace your
1004 modules. So instead of creating a I<Color> type for your
1005 B<My::Graphics> module, you would call the type
1006 I<My::Graphics::Types::Color> instead.
1008 =head2 Use with Other Constraint Modules
1010 This module can play nicely with other constraint modules with some
1011 slight tweaking. The C<where> clause in types is expected to be a
1012 C<CODE> reference which checks it's first argument and returns a
1013 boolean. Since most constraint modules work in a similar way, it
1014 should be simple to adapt them to work with Moose.
1016 For instance, this is how you could use it with
1017 L<Declare::Constraints::Simple> to declare a completely new type.
1019 type 'HashOfArrayOfObjects',
1023 -values => IsArrayRef(IsObject)
1027 For more examples see the F<t/200_examples/004_example_w_DCS.t> test
1030 Here is an example of using L<Test::Deep> and it's non-test
1031 related C<eq_deeply> function.
1033 type 'ArrayOfHashOfBarsAndRandomNumbers'
1036 array_each(subhashof({
1038 random_number => ignore()
1042 For a complete example see the
1043 F<t/200_examples/005_example_w_TestDeep.t> test file.
1047 =head2 Type Constraint Constructors
1049 The following functions are used to create type constraints. They
1050 will also register the type constraints your create in a global
1051 registry that is used to look types up by name.
1053 See the L</SYNOPSIS> for an example of how to use these.
1057 =item B<< subtype 'Name' => as 'Parent' => where { } ... >>
1059 This creates a named subtype.
1061 If you provide a parent that Moose does not recognize, it will
1062 automatically create a new class type constraint for this name.
1064 When creating a named type, the C<subtype> function should either be
1065 called with the sugar helpers (C<where>, C<message>, etc), or with a
1066 name and a hashref of parameters:
1068 subtype( 'Foo', { where => ..., message => ... } );
1070 The valid hashref keys are C<as> (the parent), C<where>, C<message>,
1073 =item B<< subtype as 'Parent' => where { } ... >>
1075 This creates an unnamed subtype and will return the type
1076 constraint meta-object, which will be an instance of
1077 L<Moose::Meta::TypeConstraint>.
1079 When creating an anonymous type, the C<subtype> function should either
1080 be called with the sugar helpers (C<where>, C<message>, etc), or with
1081 just a hashref of parameters:
1083 subtype( { where => ..., message => ... } );
1085 =item B<class_type ($class, ?$options)>
1087 Creates a new subtype of C<Object> with the name C<$class> and the
1088 metaclass L<Moose::Meta::TypeConstraint::Class>.
1090 =item B<role_type ($role, ?$options)>
1092 Creates a C<Role> type constraint with the name C<$role> and the
1093 metaclass L<Moose::Meta::TypeConstraint::Role>.
1095 =item B<maybe_type ($type)>
1097 Creates a type constraint for either C<undef> or something of the
1100 =item B<duck_type ($name, \@methods)>
1102 This will create a subtype of Object and test to make sure the value
1103 C<can()> do the methods in C<\@methods>.
1105 This is intended as an easy way to accept non-Moose objects that
1106 provide a certain interface. If you're using Moose classes, we
1107 recommend that you use a C<requires>-only Role instead.
1109 =item B<duck_type (\@methods)>
1111 If passed an ARRAY reference as the only parameter instead of the
1112 C<$name>, C<\@methods> pair, this will create an unnamed duck type.
1113 This can be used in an attribute definition like so:
1117 isa => duck_type( [qw( get_set )] ),
1120 =item B<enum ($name, \@values)>
1122 This will create a basic subtype for a given set of strings.
1123 The resulting constraint will be a subtype of C<Str> and
1124 will match any of the items in C<\@values>. It is case sensitive.
1125 See the L</SYNOPSIS> for a simple example.
1127 B<NOTE:> This is not a true proper enum type, it is simply
1128 a convenient constraint builder.
1130 =item B<enum (\@values)>
1132 If passed an ARRAY reference as the only parameter instead of the
1133 C<$name>, C<\@values> pair, this will create an unnamed enum. This
1134 can then be used in an attribute definition like so:
1136 has 'sort_order' => (
1138 isa => enum([qw[ ascending descending ]]),
1141 =item B<as 'Parent'>
1143 This is just sugar for the type constraint construction syntax.
1145 It takes a single argument, which is the name of a parent type.
1147 =item B<where { ... }>
1149 This is just sugar for the type constraint construction syntax.
1151 It takes a subroutine reference as an argument. When the type
1152 constraint is tested, the reference is run with the value to be tested
1153 in C<$_>. This reference should return true or false to indicate
1154 whether or not the constraint check passed.
1156 =item B<message { ... }>
1158 This is just sugar for the type constraint construction syntax.
1160 It takes a subroutine reference as an argument. When the type
1161 constraint fails, then the code block is run with the value provided
1162 in C<$_>. This reference should return a string, which will be used in
1163 the text of the exception thrown.
1165 =item B<optimize_as { ... }>
1167 This can be used to define a "hand optimized" version of your
1168 type constraint which can be used to avoid traversing a subtype
1169 constraint hierarchy.
1171 B<NOTE:> You should only use this if you know what you are doing.
1172 All the built in types use this, so your subtypes (assuming they
1173 are shallow) will not likely need to use this.
1175 =item B<< type 'Name' => where { } ... >>
1177 This creates a base type, which has no parent.
1179 The C<type> function should either be called with the sugar helpers
1180 (C<where>, C<message>, etc), or with a name and a hashref of
1183 type( 'Foo', { where => ..., message => ... } );
1185 The valid hashref keys are C<where>, C<message>, and C<optimize_as>.
1189 =head2 Type Constraint Utilities
1193 =item B<< match_on_type $value => ( $type => \&action, ... ?\&default ) >>
1195 This is a utility function for doing simple type based dispatching similar to
1196 match/case in OCaml and case/of in Haskell. It is not as featureful as those
1197 languages, nor does not it support any kind of automatic destructuring
1198 bind. Here is a simple Perl pretty printer dispatching over the core Moose
1203 match_on_type $x => (
1208 join ", " => map { $_ . ' => ' . ppprint( $hash->{$_} ) }
1214 '[ ' . ( join ", " => map { ppprint($_) } @$array ) . ' ]';
1216 CodeRef => sub {'sub { ... }'},
1217 RegexpRef => sub { 'qr/' . $_ . '/' },
1218 GlobRef => sub { '*' . B::svref_2object($_)->NAME },
1219 Object => sub { $_->can('to_string') ? $_->to_string : $_ },
1220 ScalarRef => sub { '\\' . ppprint( ${$_} ) },
1222 Str => sub { '"' . $_ . '"' },
1223 Undef => sub {'undef'},
1224 => sub { die "I don't know what $_ is" }
1228 Or a simple JSON serializer:
1232 match_on_type $x => (
1238 map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
1244 '[ ' . ( join ", " => map { to_json($_) } @$array ) . ' ]';
1247 Str => sub { '"' . $_ . '"' },
1248 Undef => sub {'null'},
1249 => sub { die "$_ is not acceptable json type" }
1253 The matcher is done by mapping a C<$type> to an C<\&action>. The C<$type> can
1254 be either a string type or a L<Moose::Meta::TypeConstraint> object, and
1255 C<\&action> is a subroutine reference. This function will dispatch on the
1256 first match for C<$value>. It is possible to have a catch-all by providing an
1257 additional subroutine reference as the final argument to C<match_on_type>.
1261 =head2 Type Coercion Constructors
1263 You can define coercions for type constraints, which allow you to
1264 automatically transform values to something valid for the type
1265 constraint. If you ask your accessor to coerce, then Moose will run
1266 the type-coercion code first, followed by the type constraint
1267 check. This feature should be used carefully as it is very powerful
1268 and could easily take off a limb if you are not careful.
1270 See the L</SYNOPSIS> for an example of how to use these.
1274 =item B<< coerce 'Name' => from 'OtherName' => via { ... } >>
1276 This defines a coercion from one type to another. The C<Name> argument
1277 is the type you are coercing I<to>.
1279 To define multiple coercions, supply more sets of from/via pairs:
1282 from 'OtherName' => via { ... },
1283 from 'ThirdName' => via { ... };
1285 =item B<from 'OtherName'>
1287 This is just sugar for the type coercion construction syntax.
1289 It takes a single type name (or type object), which is the type being
1292 =item B<via { ... }>
1294 This is just sugar for the type coercion construction syntax.
1296 It takes a subroutine reference. This reference will be called with
1297 the value to be coerced in C<$_>. It is expected to return a new value
1298 of the proper type for the coercion.
1302 =head2 Creating and Finding Type Constraints
1304 These are additional functions for creating and finding type
1305 constraints. Most of these functions are not available for
1306 importing. The ones that are importable as specified.
1310 =item B<find_type_constraint($type_name)>
1312 This function can be used to locate the L<Moose::Meta::TypeConstraint>
1313 object for a named type.
1315 This function is importable.
1317 =item B<register_type_constraint($type_object)>
1319 This function will register a L<Moose::Meta::TypeConstraint> with the
1320 global type registry.
1322 This function is importable.
1324 =item B<normalize_type_constraint_name($type_constraint_name)>
1326 This method takes a type constraint name and returns the normalized
1327 form. This removes any whitespace in the string.
1329 =item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
1331 This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1332 or a list of names. It returns a new
1333 L<Moose::Meta::TypeConstraint::Union> object.
1335 =item B<create_parameterized_type_constraint($type_name)>
1337 Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1338 this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1339 object. The C<BaseType> must exist already exist as a parameterizable
1342 =item B<create_class_type_constraint($class, $options)>
1344 Given a class name this function will create a new
1345 L<Moose::Meta::TypeConstraint::Class> object for that class name.
1347 The C<$options> is a hash reference that will be passed to the
1348 L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
1350 =item B<create_role_type_constraint($role, $options)>
1352 Given a role name this function will create a new
1353 L<Moose::Meta::TypeConstraint::Role> object for that role name.
1355 The C<$options> is a hash reference that will be passed to the
1356 L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
1358 =item B<create_enum_type_constraint($name, $values)>
1360 Given a enum name this function will create a new
1361 L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1363 =item B<create_duck_type_constraint($name, $methods)>
1365 Given a duck type name this function will create a new
1366 L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
1368 =item B<find_or_parse_type_constraint($type_name)>
1370 Given a type name, this first attempts to find a matching constraint
1371 in the global registry.
1373 If the type name is a union or parameterized type, it will create a
1374 new object of the appropriate, but if given a "regular" type that does
1375 not yet exist, it simply returns false.
1377 When given a union or parameterized type, the member or base type must
1380 If it creates a new union or parameterized type, it will add it to the
1383 =item B<find_or_create_isa_type_constraint($type_name)>
1385 =item B<find_or_create_does_type_constraint($type_name)>
1387 These functions will first call C<find_or_parse_type_constraint>. If
1388 that function does not return a type, a new type object will
1391 The C<isa> variant will use C<create_class_type_constraint> and the
1392 C<does> variant will use C<create_role_type_constraint>.
1394 =item B<get_type_constraint_registry>
1396 Returns the L<Moose::Meta::TypeConstraint::Registry> object which
1397 keeps track of all type constraints.
1399 =item B<list_all_type_constraints>
1401 This will return a list of type constraint names in the global
1402 registry. You can then fetch the actual type object using
1403 C<find_type_constraint($type_name)>.
1405 =item B<list_all_builtin_type_constraints>
1407 This will return a list of builtin type constraints, meaning those
1408 which are defined in this module. See the L<Default Type Constraints>
1409 section for a complete list.
1411 =item B<export_type_constraints_as_functions>
1413 This will export all the current type constraints as functions into
1414 the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1415 mostly used for testing, but it might prove useful to others.
1417 =item B<get_all_parameterizable_types>
1419 This returns all the parameterizable types that have been registered,
1420 as a list of type objects.
1422 =item B<add_parameterizable_type($type)>
1424 Adds C<$type> to the list of parameterizable types
1430 See L<Moose/BUGS> for details on reporting bugs.