2 package Moose::Util::TypeConstraints;
5 use List::MoreUtils qw( all any );
6 use Scalar::Util qw( blessed reftype );
10 $VERSION = eval $VERSION;
11 our $AUTHORITY = 'cpan:STEVAN';
13 ## --------------------------------------------------------
14 # Prototyped subs must be predeclared because we have a
15 # circular dependency with Moose::Meta::Attribute et. al.
16 # so in case of us being use'd first the predeclaration
17 # ensures the prototypes are in scope when consumers are
26 ## --------------------------------------------------------
28 use Moose::Deprecated;
29 use Moose::Meta::TypeConstraint;
30 use Moose::Meta::TypeConstraint::Union;
31 use Moose::Meta::TypeConstraint::Parameterized;
32 use Moose::Meta::TypeConstraint::Parameterizable;
33 use Moose::Meta::TypeConstraint::Class;
34 use Moose::Meta::TypeConstraint::Role;
35 use Moose::Meta::TypeConstraint::Enum;
36 use Moose::Meta::TypeConstraint::DuckType;
37 use Moose::Meta::TypeCoercion;
38 use Moose::Meta::TypeCoercion::Union;
39 use Moose::Meta::TypeConstraint::Registry;
40 use Moose::Util::TypeConstraints::OptimizedConstraints;
42 Moose::Exporter->setup_import_methods(
45 type subtype class_type role_type maybe_type duck_type
46 as where message optimize_as
50 register_type_constraint
55 ## --------------------------------------------------------
56 ## type registry and some useful functions for it
57 ## --------------------------------------------------------
59 my $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
61 sub get_type_constraint_registry {$REGISTRY}
62 sub list_all_type_constraints { keys %{ $REGISTRY->type_constraints } }
64 sub export_type_constraints_as_functions {
67 foreach my $constraint ( keys %{ $REGISTRY->type_constraints } ) {
68 my $tc = $REGISTRY->get_type_constraint($constraint)
69 ->_compiled_type_constraint;
70 *{"${pkg}::${constraint}"}
71 = sub { $tc->( $_[0] ) ? 1 : undef }; # the undef is for compat
75 sub create_type_constraint_union {
76 my @type_constraint_names;
78 if ( scalar @_ == 1 && _detect_type_constraint_union( $_[0] ) ) {
79 @type_constraint_names = _parse_type_constraint_union( $_[0] );
82 @type_constraint_names = @_;
85 ( scalar @type_constraint_names >= 2 )
86 || __PACKAGE__->_throw_error(
87 "You must pass in at least 2 type names to make a union");
89 my @type_constraints = map {
90 find_or_parse_type_constraint($_)
91 || __PACKAGE__->_throw_error(
92 "Could not locate type constraint ($_) for the union");
93 } @type_constraint_names;
95 return Moose::Meta::TypeConstraint::Union->new(
96 type_constraints => \@type_constraints );
99 sub create_parameterized_type_constraint {
100 my $type_constraint_name = shift;
101 my ( $base_type, $type_parameter )
102 = _parse_parameterized_type_constraint($type_constraint_name);
104 ( defined $base_type && defined $type_parameter )
105 || __PACKAGE__->_throw_error(
106 "Could not parse type name ($type_constraint_name) correctly");
108 if ( $REGISTRY->has_type_constraint($base_type) ) {
109 my $base_type_tc = $REGISTRY->get_type_constraint($base_type);
110 return _create_parameterized_type_constraint(
116 __PACKAGE__->_throw_error(
117 "Could not locate the base type ($base_type)");
121 sub _create_parameterized_type_constraint {
122 my ( $base_type_tc, $type_parameter ) = @_;
123 if ( $base_type_tc->can('parameterize') ) {
124 return $base_type_tc->parameterize($type_parameter);
127 return Moose::Meta::TypeConstraint::Parameterized->new(
128 name => $base_type_tc->name . '[' . $type_parameter . ']',
129 parent => $base_type_tc,
131 find_or_create_isa_type_constraint($type_parameter),
136 #should we also support optimized checks?
137 sub create_class_type_constraint {
138 my ( $class, $options ) = @_;
140 # too early for this check
141 #find_type_constraint("ClassName")->check($class)
142 # || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
150 $options{name} ||= "__ANON__";
152 Moose::Meta::TypeConstraint::Class->new(%options);
155 sub create_role_type_constraint {
156 my ( $role, $options ) = @_;
158 # too early for this check
159 #find_type_constraint("ClassName")->check($class)
160 # || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
168 $options{name} ||= "__ANON__";
170 Moose::Meta::TypeConstraint::Role->new(%options);
173 sub find_or_create_type_constraint {
174 my ( $type_constraint_name, $options_for_anon_type ) = @_;
177 = find_or_parse_type_constraint($type_constraint_name) ) {
180 elsif ( defined $options_for_anon_type ) {
183 # if there is no $options_for_anon_type
184 # specified, then we assume they don't
185 # want to create one, and return nothing.
187 # otherwise assume that we should create
188 # an ANON type with the $options_for_anon_type
189 # options which can be passed in. It should
190 # be noted that these don't get registered
191 # so we need to return it.
193 return Moose::Meta::TypeConstraint->new(
195 %{$options_for_anon_type}
202 sub find_or_create_isa_type_constraint {
203 my $type_constraint_name = shift;
204 find_or_parse_type_constraint($type_constraint_name)
205 || create_class_type_constraint($type_constraint_name);
208 sub find_or_create_does_type_constraint {
209 my $type_constraint_name = shift;
210 find_or_parse_type_constraint($type_constraint_name)
211 || create_role_type_constraint($type_constraint_name);
214 sub find_or_parse_type_constraint {
215 my $type_constraint_name = normalize_type_constraint_name(shift);
218 if ( $constraint = find_type_constraint($type_constraint_name) ) {
221 elsif ( _detect_type_constraint_union($type_constraint_name) ) {
222 $constraint = create_type_constraint_union($type_constraint_name);
224 elsif ( _detect_parameterized_type_constraint($type_constraint_name) ) {
226 = create_parameterized_type_constraint($type_constraint_name);
232 $REGISTRY->add_type_constraint($constraint);
236 sub normalize_type_constraint_name {
237 my $type_constraint_name = shift;
238 $type_constraint_name =~ s/\s//g;
239 return $type_constraint_name;
245 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
246 Carp::confess($error);
249 ## --------------------------------------------------------
250 ## exported functions ...
251 ## --------------------------------------------------------
253 sub find_type_constraint {
256 if ( blessed $type and $type->isa("Moose::Meta::TypeConstraint") ) {
260 return unless $REGISTRY->has_type_constraint($type);
261 return $REGISTRY->get_type_constraint($type);
265 sub register_type_constraint {
266 my $constraint = shift;
267 __PACKAGE__->_throw_error("can't register an unnamed type constraint")
268 unless defined $constraint->name;
269 $REGISTRY->add_type_constraint($constraint);
277 # back-compat version, called without sugar
278 if ( !any { ( reftype($_) || '' ) eq 'HASH' } @_ ) {
279 Moose::Deprecated::deprecated(
280 feature => 'type without sugar',
282 'Calling type() with a simple list of parameters is deprecated'
285 return _create_type_constraint( $_[0], undef, $_[1] );
290 my %p = map { %{$_} } @_;
292 return _create_type_constraint(
293 $name, undef, $p{where}, $p{message},
300 # crazy back-compat code for being called without sugar ...
302 # subtype 'Parent', sub { where };
303 if ( scalar @_ == 2 && ( reftype( $_[1] ) || '' ) eq 'CODE' ) {
304 Moose::Deprecated::deprecated(
305 feature => 'subtype without sugar',
307 'Calling subtype() with a simple list of parameters is deprecated'
310 return _create_type_constraint( undef, @_ );
313 # subtype 'Parent', sub { where }, sub { message };
314 # subtype 'Parent', sub { where }, sub { message }, sub { optimized };
315 if ( scalar @_ >= 3 && all { ( reftype($_) || '' ) eq 'CODE' }
317 Moose::Deprecated::deprecated(
318 feature => 'subtype without sugar',
320 'Calling subtype() with a simple list of parameters is deprecated'
323 return _create_type_constraint( undef, @_ );
326 # subtype 'Name', 'Parent', ...
327 if ( scalar @_ >= 2 && all { !ref } @_[ 0, 1 ] ) {
328 Moose::Deprecated::deprecated(
329 feature => 'subtype without sugar',
331 'Calling subtype() with a simple list of parameters is deprecated'
334 return _create_type_constraint(@_);
337 if ( @_ == 1 && !ref $_[0] ) {
338 __PACKAGE__->_throw_error(
339 'A subtype cannot consist solely of a name, it must have a parent'
343 # The blessed check is mostly to accommodate MooseX::Types, which
344 # uses an object which overloads stringification as a type name.
345 my $name = ref $_[0] && !blessed $_[0] ? undef : shift;
347 my %p = map { %{$_} } @_;
349 # subtype Str => where { ... };
350 if ( !exists $p{as} ) {
355 return _create_type_constraint(
356 $name, $p{as}, $p{where}, $p{message},
362 register_type_constraint(
363 create_class_type_constraint(
365 ( defined( $_[1] ) ? $_[1] : () ),
370 sub role_type ($;$) {
371 register_type_constraint(
372 create_role_type_constraint(
374 ( defined( $_[1] ) ? $_[1] : () ),
380 my ($type_parameter) = @_;
382 register_type_constraint(
383 $REGISTRY->get_type_constraint('Maybe')->parameterize($type_parameter)
388 my ( $type_name, @methods ) = @_;
389 if ( ref $type_name eq 'ARRAY' && !@methods ) {
390 @methods = @$type_name;
393 if ( @methods == 1 && ref $methods[0] eq 'ARRAY' ) {
394 @methods = @{ $methods[0] };
397 register_type_constraint(
398 create_duck_type_constraint(
406 my ( $type_name, @coercion_map ) = @_;
407 _install_type_coercions( $type_name, \@coercion_map );
410 # The trick of returning @_ lets us avoid having to specify a
411 # prototype. Perl will parse this:
419 # subtype( 'Foo', as( 'Str', where { ... } ) );
421 # If as() returns all it's extra arguments, this just works, and
422 # preserves backwards compatibility.
423 sub as { { as => shift }, @_ }
424 sub where (&) { { where => $_[0] } }
425 sub message (&) { { message => $_[0] } }
426 sub optimize_as (&) { { optimize_as => $_[0] } }
429 sub via (&) { $_[0] }
432 my ( $type_name, @values ) = @_;
435 # if only an array-ref is passed then
436 # you get an anon-enum
438 if ( ref $type_name eq 'ARRAY' && !@values ) {
439 @values = @$type_name;
442 if ( @values == 1 && ref $values[0] eq 'ARRAY' ) {
443 @values = @{ $values[0] };
445 ( scalar @values >= 2 )
446 || __PACKAGE__->_throw_error(
447 "You must have at least two values to enumerate through");
448 my %valid = map { $_ => 1 } @values;
450 register_type_constraint(
451 create_enum_type_constraint(
458 sub create_enum_type_constraint {
459 my ( $type_name, $values ) = @_;
461 Moose::Meta::TypeConstraint::Enum->new(
462 name => $type_name || '__ANON__',
467 sub create_duck_type_constraint {
468 my ( $type_name, $methods ) = @_;
470 Moose::Meta::TypeConstraint::DuckType->new(
471 name => $type_name || '__ANON__',
477 my ($to_match, @cases) = @_;
479 if (@cases % 2 != 0) {
480 $default = pop @cases;
481 (ref $default eq 'CODE')
482 || __PACKAGE__->_throw_error("Default case must be a CODE ref, not $default");
485 my ($type, $action) = splice @cases, 0, 2;
487 unless (blessed $type && $type->isa('Moose::Meta::TypeConstraint')) {
488 $type = find_or_parse_type_constraint($type)
489 || __PACKAGE__->_throw_error("Cannot find or parse the type '$type'")
492 (ref $action eq 'CODE')
493 || __PACKAGE__->_throw_error("Match action must be a CODE ref, not $action");
495 if ($type->check($to_match)) {
496 local $_ = $to_match;
497 return $action->($to_match);
501 || __PACKAGE__->_throw_error("No cases matched for $to_match");
503 local $_ = $to_match;
504 return $default->($to_match);
509 ## --------------------------------------------------------
510 ## desugaring functions ...
511 ## --------------------------------------------------------
513 sub _create_type_constraint ($$$;$$) {
518 my $optimized = shift;
520 my $pkg_defined_in = scalar( caller(1) );
522 if ( defined $name ) {
523 my $type = $REGISTRY->get_type_constraint($name);
525 ( $type->_package_defined_in eq $pkg_defined_in )
527 "The type constraint '$name' has already been created in "
528 . $type->_package_defined_in
529 . " and cannot be created again in "
533 $name =~ /^[\w:\.]+$/
534 or die qq{$name contains invalid characters for a type name.}
535 . qq{ Names can contain alphanumeric character, ":", and "."\n};
540 package_defined_in => $pkg_defined_in,
542 ( $check ? ( constraint => $check ) : () ),
543 ( $message ? ( message => $message ) : () ),
544 ( $optimized ? ( optimized => $optimized ) : () ),
553 : find_or_create_isa_type_constraint($parent)
555 $constraint = $parent->create_child_type(%opts);
558 $constraint = Moose::Meta::TypeConstraint->new(%opts);
561 $REGISTRY->add_type_constraint($constraint)
567 sub _install_type_coercions ($$) {
568 my ( $type_name, $coercion_map ) = @_;
569 my $type = find_type_constraint($type_name);
571 || __PACKAGE__->_throw_error(
572 "Cannot find type '$type_name', perhaps you forgot to load it");
573 if ( $type->has_coercion ) {
574 $type->coercion->add_type_coercions(@$coercion_map);
577 my $type_coercion = Moose::Meta::TypeCoercion->new(
578 type_coercion_map => $coercion_map,
579 type_constraint => $type
581 $type->coercion($type_coercion);
585 ## --------------------------------------------------------
586 ## type notation parsing ...
587 ## --------------------------------------------------------
591 # All I have to say is mugwump++ cause I know
592 # do not even have enough regexp-fu to be able
593 # to have written this (I can only barely
594 # understand it as it is)
599 my $valid_chars = qr{[\w:\.]};
600 my $type_atom = qr{ (?>$valid_chars+) }x;
601 my $ws = qr{ (?>\s*) }x;
602 my $op_union = qr{ $ws \| $ws }x;
604 my ($type, $type_capture_parts, $type_with_parameter, $union, $any);
605 if (Class::MOP::IS_RUNNING_ON_5_10) {
607 = q{ (?&type_atom) (?: \[ (?&ws) (?&any) (?&ws) \] )? };
608 my $type_capture_parts_pattern
609 = q{ ((?&type_atom)) (?: \[ (?&ws) ((?&any)) (?&ws) \] )? };
610 my $type_with_parameter_pattern
611 = q{ (?&type_atom) \[ (?&ws) (?&any) (?&ws) \] };
613 = q{ (?&type) (?> (?: (?&op_union) (?&type) )+ ) };
615 = q{ (?&type) | (?&union) };
617 my $defines = qr{(?(DEFINE)
618 (?<valid_chars> $valid_chars)
619 (?<type_atom> $type_atom)
621 (?<op_union> $op_union)
622 (?<type> $type_pattern)
623 (?<type_capture_parts> $type_capture_parts_pattern)
624 (?<type_with_parameter> $type_with_parameter_pattern)
625 (?<union> $union_pattern)
626 (?<any> $any_pattern)
629 $type = qr{ $type_pattern $defines }x;
630 $type_capture_parts = qr{ $type_capture_parts_pattern $defines }x;
631 $type_with_parameter = qr{ $type_with_parameter_pattern $defines }x;
632 $union = qr{ $union_pattern $defines }x;
633 $any = qr{ $any_pattern $defines }x;
637 = qr{ $type_atom (?: \[ $ws (??{$any}) $ws \] )? }x;
639 = qr{ ($type_atom) (?: \[ $ws ((??{$any})) $ws \] )? }x;
641 = qr{ $type_atom \[ $ws (??{$any}) $ws \] }x;
643 = qr{ $type (?> (?: $op_union $type )+ ) }x;
645 = qr{ $type | $union }x;
649 sub _parse_parameterized_type_constraint {
650 { no warnings 'void'; $any; } # force capture of interpolated lexical
651 $_[0] =~ m{ $type_capture_parts }x;
655 sub _detect_parameterized_type_constraint {
656 { no warnings 'void'; $any; } # force capture of interpolated lexical
657 $_[0] =~ m{ ^ $type_with_parameter $ }x;
660 sub _parse_type_constraint_union {
661 { no warnings 'void'; $any; } # force capture of interpolated lexical
664 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
667 ( pos($given) eq length($given) )
668 || __PACKAGE__->_throw_error( "'$given' didn't parse (parse-pos="
676 sub _detect_type_constraint_union {
677 { no warnings 'void'; $any; } # force capture of interpolated lexical
678 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
682 ## --------------------------------------------------------
683 # define some basic built-in types
684 ## --------------------------------------------------------
686 # By making these classes immutable before creating all the types we
687 # below, we avoid repeatedly calling the slow MOP-based accessors.
689 inline_constructor => 1,
690 constructor_name => "_new",
692 # these are Class::MOP accessors, so they need inlining
693 inline_accessors => 1
694 ) for grep { $_->is_mutable }
695 map { Class::MOP::class_of($_) }
697 Moose::Meta::TypeConstraint
698 Moose::Meta::TypeConstraint::Union
699 Moose::Meta::TypeConstraint::Parameterized
700 Moose::Meta::TypeConstraint::Parameterizable
701 Moose::Meta::TypeConstraint::Class
702 Moose::Meta::TypeConstraint::Role
703 Moose::Meta::TypeConstraint::Enum
704 Moose::Meta::TypeConstraint::DuckType
705 Moose::Meta::TypeConstraint::Registry
708 type 'Any' => where {1}; # meta-type including all
709 subtype 'Item' => as 'Any'; # base-type
711 subtype 'Undef' => as 'Item' => where { !defined($_) };
712 subtype 'Defined' => as 'Item' => where { defined($_) };
714 subtype 'Bool' => as 'Item' =>
715 where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
717 subtype 'Value' => as 'Defined' => where { !ref($_) } =>
718 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
720 subtype 'Ref' => as 'Defined' => where { ref($_) } =>
721 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
723 subtype 'Str' => as 'Value' => where { ref(\$_) eq 'SCALAR' } =>
724 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
726 subtype 'Num' => as 'Str' =>
727 where { Scalar::Util::looks_like_number($_) } =>
728 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
730 subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } =>
731 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
733 subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
734 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
735 subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } =>
737 \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
738 subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
739 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
742 # scalar filehandles are GLOB refs,
743 # but a GLOB ref is not always a filehandle
744 subtype 'FileHandle' => as 'GlobRef' => where {
745 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
747 \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
750 # blessed(qr/.../) returns true,.. how odd
751 subtype 'Object' => as 'Ref' =>
752 where { blessed($_) && blessed($_) ne 'Regexp' } =>
753 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
755 # This type is deprecated.
756 subtype 'Role' => as 'Object' => where { $_->can('does') } =>
757 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
759 my $_class_name_checker = sub { };
761 subtype 'ClassName' => as 'Str' =>
762 where { Class::MOP::is_class_loaded($_) } => optimize_as
763 \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
765 subtype 'RoleName' => as 'ClassName' => where {
766 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
768 \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
770 ## --------------------------------------------------------
771 # parameterizable types ...
773 $REGISTRY->add_type_constraint(
774 Moose::Meta::TypeConstraint::Parameterizable->new(
776 package_defined_in => __PACKAGE__,
777 parent => find_type_constraint('Ref'),
778 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
780 \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef,
781 constraint_generator => sub {
782 my $type_parameter = shift;
783 my $check = $type_parameter->_compiled_type_constraint;
785 return $check->(${ $_ });
791 $REGISTRY->add_type_constraint(
792 Moose::Meta::TypeConstraint::Parameterizable->new(
794 package_defined_in => __PACKAGE__,
795 parent => find_type_constraint('Ref'),
796 constraint => sub { ref($_) eq 'ARRAY' },
798 \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
799 constraint_generator => sub {
800 my $type_parameter = shift;
801 my $check = $type_parameter->_compiled_type_constraint;
803 foreach my $x (@$_) {
804 ( $check->($x) ) || return;
812 $REGISTRY->add_type_constraint(
813 Moose::Meta::TypeConstraint::Parameterizable->new(
815 package_defined_in => __PACKAGE__,
816 parent => find_type_constraint('Ref'),
817 constraint => sub { ref($_) eq 'HASH' },
819 \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
820 constraint_generator => sub {
821 my $type_parameter = shift;
822 my $check = $type_parameter->_compiled_type_constraint;
824 foreach my $x ( values %$_ ) {
825 ( $check->($x) ) || return;
833 $REGISTRY->add_type_constraint(
834 Moose::Meta::TypeConstraint::Parameterizable->new(
836 package_defined_in => __PACKAGE__,
837 parent => find_type_constraint('Item'),
838 constraint => sub {1},
839 constraint_generator => sub {
840 my $type_parameter = shift;
841 my $check = $type_parameter->_compiled_type_constraint;
843 return 1 if not( defined($_) ) || $check->($_);
850 my @PARAMETERIZABLE_TYPES
851 = map { $REGISTRY->get_type_constraint($_) } qw[ScalarRef ArrayRef HashRef Maybe];
853 sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
855 sub add_parameterizable_type {
858 && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
859 || __PACKAGE__->_throw_error(
860 "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
862 push @PARAMETERIZABLE_TYPES => $type;
865 ## --------------------------------------------------------
866 # end of built-in types ...
867 ## --------------------------------------------------------
870 my @BUILTINS = list_all_type_constraints();
871 sub list_all_builtin_type_constraints {@BUILTINS}
878 goto &Moose::throw_error;
889 Moose::Util::TypeConstraints - Type constraint system for Moose
893 use Moose::Util::TypeConstraints;
899 subtype 'NaturalLessThanTen'
902 => message { "This number ($_) is not less than ten!" };
908 enum 'RGBColors' => qw(red green blue);
910 no Moose::Util::TypeConstraints;
914 This module provides Moose with the ability to create custom type
915 constraints to be used in attribute definition.
917 =head2 Important Caveat
919 This is B<NOT> a type system for Perl 5. These are type constraints,
920 and they are not used by Moose unless you tell it to. No type
921 inference is performed, expressions are not typed, etc. etc. etc.
923 A type constraint is at heart a small "check if a value is valid"
924 function. A constraint can be associated with an attribute. This
925 simplifies parameter validation, and makes your code clearer to read,
926 because you can refer to constraints by name.
928 =head2 Slightly Less Important Caveat
930 It is B<always> a good idea to quote your type names.
932 This prevents Perl from trying to execute the call as an indirect
933 object call. This can be an issue when you have a subtype with the
934 same name as a valid class.
938 subtype DateTime => as Object => where { $_->isa('DateTime') };
940 will I<just work>, while this:
943 subtype DateTime => as Object => where { $_->isa('DateTime') };
945 will fail silently and cause many headaches. The simple way to solve
946 this, as well as future proof your subtypes from classes which have
947 yet to have been created, is to quote the type name:
950 subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
952 =head2 Default Type Constraints
954 This module also provides a simple hierarchy for Perl 5 types, here is
955 that hierarchy represented visually.
979 B<NOTE:> Any type followed by a type parameter C<[`a]> can be
980 parameterized, this means you can say:
982 ArrayRef[Int] # an array of integers
983 HashRef[CodeRef] # a hash of str to CODE ref mappings
984 ScalarRef[Int] # a reference to an integer
985 Maybe[Str] # value may be a string, may be undefined
987 If Moose finds a name in brackets that it does not recognize as an
988 existing type, it assumes that this is a class name, for example
989 C<ArrayRef[DateTime]>.
991 B<NOTE:> Unless you parameterize a type, then it is invalid to include
992 the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
993 name, I<not> as a parameterization of C<ArrayRef>.
995 B<NOTE:> The C<Undef> type constraint for the most part works
996 correctly now, but edge cases may still exist, please use it
999 B<NOTE:> The C<ClassName> type constraint does a complex package
1000 existence check. This means that your class B<must> be loaded for this
1001 type constraint to pass.
1003 B<NOTE:> The C<RoleName> constraint checks a string is a I<package
1004 name> which is a role, like C<'MyApp::Role::Comparable'>.
1006 =head2 Type Constraint Naming
1008 Type name declared via this module can only contain alphanumeric
1009 characters, colons (:), and periods (.).
1011 Since the types created by this module are global, it is suggested
1012 that you namespace your types just as you would namespace your
1013 modules. So instead of creating a I<Color> type for your
1014 B<My::Graphics> module, you would call the type
1015 I<My::Graphics::Types::Color> instead.
1017 =head2 Use with Other Constraint Modules
1019 This module can play nicely with other constraint modules with some
1020 slight tweaking. The C<where> clause in types is expected to be a
1021 C<CODE> reference which checks it's first argument and returns a
1022 boolean. Since most constraint modules work in a similar way, it
1023 should be simple to adapt them to work with Moose.
1025 For instance, this is how you could use it with
1026 L<Declare::Constraints::Simple> to declare a completely new type.
1028 type 'HashOfArrayOfObjects',
1032 -values => IsArrayRef(IsObject)
1036 For more examples see the F<t/200_examples/004_example_w_DCS.t> test
1039 Here is an example of using L<Test::Deep> and it's non-test
1040 related C<eq_deeply> function.
1042 type 'ArrayOfHashOfBarsAndRandomNumbers'
1045 array_each(subhashof({
1047 random_number => ignore()
1051 For a complete example see the
1052 F<t/200_examples/005_example_w_TestDeep.t> test file.
1056 =head2 Type Constraint Constructors
1058 The following functions are used to create type constraints. They
1059 will also register the type constraints your create in a global
1060 registry that is used to look types up by name.
1062 See the L</SYNOPSIS> for an example of how to use these.
1066 =item B<< subtype 'Name' => as 'Parent' => where { } ... >>
1068 This creates a named subtype.
1070 If you provide a parent that Moose does not recognize, it will
1071 automatically create a new class type constraint for this name.
1073 When creating a named type, the C<subtype> function should either be
1074 called with the sugar helpers (C<where>, C<message>, etc), or with a
1075 name and a hashref of parameters:
1077 subtype( 'Foo', { where => ..., message => ... } );
1079 The valid hashref keys are C<as> (the parent), C<where>, C<message>,
1082 =item B<< subtype as 'Parent' => where { } ... >>
1084 This creates an unnamed subtype and will return the type
1085 constraint meta-object, which will be an instance of
1086 L<Moose::Meta::TypeConstraint>.
1088 When creating an anonymous type, the C<subtype> function should either
1089 be called with the sugar helpers (C<where>, C<message>, etc), or with
1090 just a hashref of parameters:
1092 subtype( { where => ..., message => ... } );
1094 =item B<class_type ($class, ?$options)>
1096 Creates a new subtype of C<Object> with the name C<$class> and the
1097 metaclass L<Moose::Meta::TypeConstraint::Class>.
1099 =item B<role_type ($role, ?$options)>
1101 Creates a C<Role> type constraint with the name C<$role> and the
1102 metaclass L<Moose::Meta::TypeConstraint::Role>.
1104 =item B<maybe_type ($type)>
1106 Creates a type constraint for either C<undef> or something of the
1109 =item B<duck_type ($name, \@methods)>
1111 This will create a subtype of Object and test to make sure the value
1112 C<can()> do the methods in C<\@methods>.
1114 This is intended as an easy way to accept non-Moose objects that
1115 provide a certain interface. If you're using Moose classes, we
1116 recommend that you use a C<requires>-only Role instead.
1118 =item B<duck_type (\@methods)>
1120 If passed an ARRAY reference as the only parameter instead of the
1121 C<$name>, C<\@methods> pair, this will create an unnamed duck type.
1122 This can be used in an attribute definition like so:
1126 isa => duck_type( [qw( get_set )] ),
1129 =item B<enum ($name, \@values)>
1131 This will create a basic subtype for a given set of strings.
1132 The resulting constraint will be a subtype of C<Str> and
1133 will match any of the items in C<\@values>. It is case sensitive.
1134 See the L</SYNOPSIS> for a simple example.
1136 B<NOTE:> This is not a true proper enum type, it is simply
1137 a convenient constraint builder.
1139 =item B<enum (\@values)>
1141 If passed an ARRAY reference as the only parameter instead of the
1142 C<$name>, C<\@values> pair, this will create an unnamed enum. This
1143 can then be used in an attribute definition like so:
1145 has 'sort_order' => (
1147 isa => enum([qw[ ascending descending ]]),
1150 =item B<as 'Parent'>
1152 This is just sugar for the type constraint construction syntax.
1154 It takes a single argument, which is the name of a parent type.
1156 =item B<where { ... }>
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 is tested, the reference is run with the value to be tested
1162 in C<$_>. This reference should return true or false to indicate
1163 whether or not the constraint check passed.
1165 =item B<message { ... }>
1167 This is just sugar for the type constraint construction syntax.
1169 It takes a subroutine reference as an argument. When the type
1170 constraint fails, then the code block is run with the value provided
1171 in C<$_>. This reference should return a string, which will be used in
1172 the text of the exception thrown.
1174 =item B<optimize_as { ... }>
1176 This can be used to define a "hand optimized" version of your
1177 type constraint which can be used to avoid traversing a subtype
1178 constraint hierarchy.
1180 B<NOTE:> You should only use this if you know what you are doing,
1181 all the built in types use this, so your subtypes (assuming they
1182 are shallow) will not likely need to use this.
1184 =item B<< type 'Name' => where { } ... >>
1186 This creates a base type, which has no parent.
1188 The C<type> function should either be called with the sugar helpers
1189 (C<where>, C<message>, etc), or with a name and a hashref of
1192 type( 'Foo', { where => ..., message => ... } );
1194 The valid hashref keys are C<where>, C<message>, and C<optimize_as>.
1198 =head2 Type Constraint Utilities
1202 =item B<< match_on_type $value => ( $type => \&action, ... ?\&default ) >>
1204 This is a utility function for doing simple type based dispatching similar to
1205 match/case in OCaml and case/of in Haskell. It is not as featureful as those
1206 languages, nor does not it support any kind of automatic destructuring
1207 bind. Here is a simple Perl pretty printer dispatching over the core Moose
1212 match_on_type $x => (
1217 join ", " => map { $_ . ' => ' . ppprint( $hash->{$_} ) }
1223 '[ ' . ( join ", " => map { ppprint($_) } @$array ) . ' ]';
1225 CodeRef => sub {'sub { ... }'},
1226 RegexpRef => sub { 'qr/' . $_ . '/' },
1227 GlobRef => sub { '*' . B::svref_2object($_)->NAME },
1228 Object => sub { $_->can('to_string') ? $_->to_string : $_ },
1229 ScalarRef => sub { '\\' . ppprint( ${$_} ) },
1231 Str => sub { '"' . $_ . '"' },
1232 Undef => sub {'undef'},
1233 => sub { die "I don't know what $_ is" }
1237 Or a simple JSON serializer:
1241 match_on_type $x => (
1247 map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
1253 '[ ' . ( join ", " => map { to_json($_) } @$array ) . ' ]';
1256 Str => sub { '"' . $_ . '"' },
1257 Undef => sub {'null'},
1258 => sub { die "$_ is not acceptable json type" }
1262 The matcher is done by mapping a C<$type> to an C<\&action>. The C<$type> can
1263 be either a string type or a L<Moose::Meta::TypeConstraint> object, and
1264 C<\&action> is a subroutine reference. This function will dispatch on the
1265 first match for C<$value>. It is possible to have a catch-all by providing an
1266 additional subroutine reference as the final argument to C<match_on_type>.
1270 =head2 Type Coercion Constructors
1272 You can define coercions for type constraints, which allow you to
1273 automatically transform values to something valid for the type
1274 constraint. If you ask your accessor to coerce, then Moose will run
1275 the type-coercion code first, followed by the type constraint
1276 check. This feature should be used carefully as it is very powerful
1277 and could easily take off a limb if you are not careful.
1279 See the L</SYNOPSIS> for an example of how to use these.
1283 =item B<< coerce 'Name' => from 'OtherName' => via { ... } >>
1285 This defines a coercion from one type to another. The C<Name> argument
1286 is the type you are coercing I<to>.
1288 =item B<from 'OtherName'>
1290 This is just sugar for the type coercion construction syntax.
1292 It takes a single type name (or type object), which is the type being
1295 =item B<via { ... }>
1297 This is just sugar for the type coercion construction syntax.
1299 It takes a subroutine reference. This reference will be called with
1300 the value to be coerced in C<$_>. It is expected to return a new value
1301 of the proper type for the coercion.
1305 =head2 Creating and Finding Type Constraints
1307 These are additional functions for creating and finding type
1308 constraints. Most of these functions are not available for
1309 importing. The ones that are importable as specified.
1313 =item B<find_type_constraint($type_name)>
1315 This function can be used to locate the L<Moose::Meta::TypeConstraint>
1316 object for a named type.
1318 This function is importable.
1320 =item B<register_type_constraint($type_object)>
1322 This function will register a L<Moose::Meta::TypeConstraint> with the
1323 global type registry.
1325 This function is importable.
1327 =item B<normalize_type_constraint_name($type_constraint_name)>
1329 This method takes a type constraint name and returns the normalized
1330 form. This removes any whitespace in the string.
1332 =item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
1334 This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1335 or a list of names. It returns a new
1336 L<Moose::Meta::TypeConstraint::Union> object.
1338 =item B<create_parameterized_type_constraint($type_name)>
1340 Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1341 this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1342 object. The C<BaseType> must exist already exist as a parameterizable
1345 =item B<create_class_type_constraint($class, $options)>
1347 Given a class name this function will create a new
1348 L<Moose::Meta::TypeConstraint::Class> object for that class name.
1350 The C<$options> is a hash reference that will be passed to the
1351 L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
1353 =item B<create_role_type_constraint($role, $options)>
1355 Given a role name this function will create a new
1356 L<Moose::Meta::TypeConstraint::Role> object for that role name.
1358 The C<$options> is a hash reference that will be passed to the
1359 L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
1361 =item B<create_enum_type_constraint($name, $values)>
1363 Given a enum name this function will create a new
1364 L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1366 =item B<create_duck_type_constraint($name, $methods)>
1368 Given a duck type name this function will create a new
1369 L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
1371 =item B<find_or_parse_type_constraint($type_name)>
1373 Given a type name, this first attempts to find a matching constraint
1374 in the global registry.
1376 If the type name is a union or parameterized type, it will create a
1377 new object of the appropriate, but if given a "regular" type that does
1378 not yet exist, it simply returns false.
1380 When given a union or parameterized type, the member or base type must
1383 If it creates a new union or parameterized type, it will add it to the
1386 =item B<find_or_create_isa_type_constraint($type_name)>
1388 =item B<find_or_create_does_type_constraint($type_name)>
1390 These functions will first call C<find_or_parse_type_constraint>. If
1391 that function does not return a type, a new anonymous type object will
1394 The C<isa> variant will use C<create_class_type_constraint> and the
1395 C<does> variant will use C<create_role_type_constraint>.
1397 =item B<get_type_constraint_registry>
1399 Returns the L<Moose::Meta::TypeConstraint::Registry> object which
1400 keeps track of all type constraints.
1402 =item B<list_all_type_constraints>
1404 This will return a list of type constraint names in the global
1405 registry. You can then fetch the actual type object using
1406 C<find_type_constraint($type_name)>.
1408 =item B<list_all_builtin_type_constraints>
1410 This will return a list of builtin type constraints, meaning those
1411 which are defined in this module. See the L<Default Type Constraints>
1412 section for a complete list.
1414 =item B<export_type_constraints_as_functions>
1416 This will export all the current type constraints as functions into
1417 the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1418 mostly used for testing, but it might prove useful to others.
1420 =item B<get_all_parameterizable_types>
1422 This returns all the parameterizable types that have been registered,
1423 as a list of type objects.
1425 =item B<add_parameterizable_type($type)>
1427 Adds C<$type> to the list of parameterizable types
1433 See L<Moose/BUGS> for details on reporting bugs.
1437 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1439 =head1 COPYRIGHT AND LICENSE
1441 Copyright 2006-2010 by Infinity Interactive, Inc.
1443 L<http://www.iinteractive.com>
1445 This library is free software; you can redistribute it and/or modify
1446 it under the same terms as Perl itself.