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::Meta::TypeConstraint;
29 use Moose::Meta::TypeConstraint::Union;
30 use Moose::Meta::TypeConstraint::Parameterized;
31 use Moose::Meta::TypeConstraint::Parameterizable;
32 use Moose::Meta::TypeConstraint::Class;
33 use Moose::Meta::TypeConstraint::Role;
34 use Moose::Meta::TypeConstraint::Enum;
35 use Moose::Meta::TypeConstraint::DuckType;
36 use Moose::Meta::TypeCoercion;
37 use Moose::Meta::TypeCoercion::Union;
38 use Moose::Meta::TypeConstraint::Registry;
39 use Moose::Util::TypeConstraints::OptimizedConstraints;
41 Moose::Exporter->setup_import_methods(
44 type subtype class_type role_type maybe_type duck_type
45 as where message optimize_as
49 register_type_constraint
54 ## --------------------------------------------------------
55 ## type registry and some useful functions for it
56 ## --------------------------------------------------------
58 my $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
60 sub get_type_constraint_registry {$REGISTRY}
61 sub list_all_type_constraints { keys %{ $REGISTRY->type_constraints } }
63 sub export_type_constraints_as_functions {
66 foreach my $constraint ( keys %{ $REGISTRY->type_constraints } ) {
67 my $tc = $REGISTRY->get_type_constraint($constraint)
68 ->_compiled_type_constraint;
69 *{"${pkg}::${constraint}"}
70 = sub { $tc->( $_[0] ) ? 1 : undef }; # the undef is for compat
74 sub create_type_constraint_union {
75 my @type_constraint_names;
77 if ( scalar @_ == 1 && _detect_type_constraint_union( $_[0] ) ) {
78 @type_constraint_names = _parse_type_constraint_union( $_[0] );
81 @type_constraint_names = @_;
84 ( scalar @type_constraint_names >= 2 )
85 || __PACKAGE__->_throw_error(
86 "You must pass in at least 2 type names to make a union");
88 my @type_constraints = map {
89 find_or_parse_type_constraint($_)
90 || __PACKAGE__->_throw_error(
91 "Could not locate type constraint ($_) for the union");
92 } @type_constraint_names;
94 return Moose::Meta::TypeConstraint::Union->new(
95 type_constraints => \@type_constraints );
98 sub create_parameterized_type_constraint {
99 my $type_constraint_name = shift;
100 my ( $base_type, $type_parameter )
101 = _parse_parameterized_type_constraint($type_constraint_name);
103 ( defined $base_type && defined $type_parameter )
104 || __PACKAGE__->_throw_error(
105 "Could not parse type name ($type_constraint_name) correctly");
107 if ( $REGISTRY->has_type_constraint($base_type) ) {
108 my $base_type_tc = $REGISTRY->get_type_constraint($base_type);
109 return _create_parameterized_type_constraint(
115 __PACKAGE__->_throw_error(
116 "Could not locate the base type ($base_type)");
120 sub _create_parameterized_type_constraint {
121 my ( $base_type_tc, $type_parameter ) = @_;
122 if ( $base_type_tc->can('parameterize') ) {
123 return $base_type_tc->parameterize($type_parameter);
126 return Moose::Meta::TypeConstraint::Parameterized->new(
127 name => $base_type_tc->name . '[' . $type_parameter . ']',
128 parent => $base_type_tc,
130 find_or_create_isa_type_constraint($type_parameter),
135 #should we also support optimized checks?
136 sub create_class_type_constraint {
137 my ( $class, $options ) = @_;
139 # too early for this check
140 #find_type_constraint("ClassName")->check($class)
141 # || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
149 $options{name} ||= "__ANON__";
151 Moose::Meta::TypeConstraint::Class->new(%options);
154 sub create_role_type_constraint {
155 my ( $role, $options ) = @_;
157 # too early for this check
158 #find_type_constraint("ClassName")->check($class)
159 # || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
167 $options{name} ||= "__ANON__";
169 Moose::Meta::TypeConstraint::Role->new(%options);
172 sub find_or_create_type_constraint {
173 my ( $type_constraint_name, $options_for_anon_type ) = @_;
176 = find_or_parse_type_constraint($type_constraint_name) ) {
179 elsif ( defined $options_for_anon_type ) {
182 # if there is no $options_for_anon_type
183 # specified, then we assume they don't
184 # want to create one, and return nothing.
186 # otherwise assume that we should create
187 # an ANON type with the $options_for_anon_type
188 # options which can be passed in. It should
189 # be noted that these don't get registered
190 # so we need to return it.
192 return Moose::Meta::TypeConstraint->new(
194 %{$options_for_anon_type}
201 sub find_or_create_isa_type_constraint {
202 my $type_constraint_name = shift;
203 find_or_parse_type_constraint($type_constraint_name)
204 || create_class_type_constraint($type_constraint_name);
207 sub find_or_create_does_type_constraint {
208 my $type_constraint_name = shift;
209 find_or_parse_type_constraint($type_constraint_name)
210 || create_role_type_constraint($type_constraint_name);
213 sub find_or_parse_type_constraint {
214 my $type_constraint_name = normalize_type_constraint_name(shift);
217 if ( $constraint = find_type_constraint($type_constraint_name) ) {
220 elsif ( _detect_type_constraint_union($type_constraint_name) ) {
221 $constraint = create_type_constraint_union($type_constraint_name);
223 elsif ( _detect_parameterized_type_constraint($type_constraint_name) ) {
225 = create_parameterized_type_constraint($type_constraint_name);
231 $REGISTRY->add_type_constraint($constraint);
235 sub normalize_type_constraint_name {
236 my $type_constraint_name = shift;
237 $type_constraint_name =~ s/\s//g;
238 return $type_constraint_name;
244 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
245 Carp::confess($error);
248 ## --------------------------------------------------------
249 ## exported functions ...
250 ## --------------------------------------------------------
252 sub find_type_constraint {
255 if ( blessed $type and $type->isa("Moose::Meta::TypeConstraint") ) {
259 return unless $REGISTRY->has_type_constraint($type);
260 return $REGISTRY->get_type_constraint($type);
264 sub register_type_constraint {
265 my $constraint = shift;
266 __PACKAGE__->_throw_error("can't register an unnamed type constraint")
267 unless defined $constraint->name;
268 $REGISTRY->add_type_constraint($constraint);
276 # back-compat version, called without sugar
277 if ( !any { ( reftype($_) || '' ) eq 'HASH' } @_ ) {
278 return _create_type_constraint( $_[0], undef, $_[1] );
283 my %p = map { %{$_} } @_;
285 return _create_type_constraint(
286 $name, undef, $p{where}, $p{message},
293 # crazy back-compat code for being called without sugar ...
295 # subtype 'Parent', sub { where };
296 if ( scalar @_ == 2 && ( reftype( $_[1] ) || '' ) eq 'CODE' ) {
297 return _create_type_constraint( undef, @_ );
300 # subtype 'Parent', sub { where }, sub { message };
301 # subtype 'Parent', sub { where }, sub { message }, sub { optimized };
302 if ( scalar @_ >= 3 && all { ( reftype($_) || '' ) eq 'CODE' }
304 return _create_type_constraint( undef, @_ );
307 # subtype 'Name', 'Parent', ...
308 if ( scalar @_ >= 2 && all { !ref } @_[ 0, 1 ] ) {
309 return _create_type_constraint(@_);
312 if ( @_ == 1 && !ref $_[0] ) {
313 __PACKAGE__->_throw_error(
314 'A subtype cannot consist solely of a name, it must have a parent'
318 # The blessed check is mostly to accommodate MooseX::Types, which
319 # uses an object which overloads stringification as a type name.
320 my $name = ref $_[0] && !blessed $_[0] ? undef : shift;
322 my %p = map { %{$_} } @_;
324 # subtype Str => where { ... };
325 if ( !exists $p{as} ) {
330 return _create_type_constraint(
331 $name, $p{as}, $p{where}, $p{message},
337 register_type_constraint(
338 create_class_type_constraint(
340 ( defined( $_[1] ) ? $_[1] : () ),
345 sub role_type ($;$) {
346 register_type_constraint(
347 create_role_type_constraint(
349 ( defined( $_[1] ) ? $_[1] : () ),
355 my ($type_parameter) = @_;
357 register_type_constraint(
358 $REGISTRY->get_type_constraint('Maybe')->parameterize($type_parameter)
363 my ( $type_name, @methods ) = @_;
364 if ( ref $type_name eq 'ARRAY' && !@methods ) {
365 @methods = @$type_name;
368 if ( @methods == 1 && ref $methods[0] eq 'ARRAY' ) {
369 @methods = @{ $methods[0] };
372 register_type_constraint(
373 create_duck_type_constraint(
381 my ( $type_name, @coercion_map ) = @_;
382 _install_type_coercions( $type_name, \@coercion_map );
385 # The trick of returning @_ lets us avoid having to specify a
386 # prototype. Perl will parse this:
394 # subtype( 'Foo', as( 'Str', where { ... } ) );
396 # If as() returns all it's extra arguments, this just works, and
397 # preserves backwards compatibility.
398 sub as { { as => shift }, @_ }
399 sub where (&) { { where => $_[0] } }
400 sub message (&) { { message => $_[0] } }
401 sub optimize_as (&) { { optimize_as => $_[0] } }
404 sub via (&) { $_[0] }
407 my ( $type_name, @values ) = @_;
410 # if only an array-ref is passed then
411 # you get an anon-enum
413 if ( ref $type_name eq 'ARRAY' && !@values ) {
414 @values = @$type_name;
417 if ( @values == 1 && ref $values[0] eq 'ARRAY' ) {
418 @values = @{ $values[0] };
420 ( scalar @values >= 2 )
421 || __PACKAGE__->_throw_error(
422 "You must have at least two values to enumerate through");
423 my %valid = map { $_ => 1 } @values;
425 register_type_constraint(
426 create_enum_type_constraint(
433 sub create_enum_type_constraint {
434 my ( $type_name, $values ) = @_;
436 Moose::Meta::TypeConstraint::Enum->new(
437 name => $type_name || '__ANON__',
442 sub create_duck_type_constraint {
443 my ( $type_name, $methods ) = @_;
445 Moose::Meta::TypeConstraint::DuckType->new(
446 name => $type_name || '__ANON__',
452 my ($to_match, @cases) = @_;
454 if (@cases % 2 != 0) {
455 $default = pop @cases;
456 (ref $default eq 'CODE')
457 || __PACKAGE__->_throw_error("Default case must be a CODE ref, not $default");
460 my ($type, $action) = splice @cases, 0, 2;
462 unless (blessed $type && $type->isa('Moose::Meta::TypeConstraint')) {
463 $type = find_or_parse_type_constraint($type)
464 || __PACKAGE__->_throw_error("Cannot find or parse the type '$type'")
467 (ref $action eq 'CODE')
468 || __PACKAGE__->_throw_error("Match action must be a CODE ref, not $action");
470 if ($type->check($to_match)) {
471 local $_ = $to_match;
472 return $action->($to_match);
476 || __PACKAGE__->_throw_error("No cases matched for $to_match");
478 local $_ = $to_match;
479 return $default->($to_match);
484 ## --------------------------------------------------------
485 ## desugaring functions ...
486 ## --------------------------------------------------------
488 sub _create_type_constraint ($$$;$$) {
493 my $optimized = shift;
495 my $pkg_defined_in = scalar( caller(1) );
497 if ( defined $name ) {
498 my $type = $REGISTRY->get_type_constraint($name);
500 ( $type->_package_defined_in eq $pkg_defined_in )
502 "The type constraint '$name' has already been created in "
503 . $type->_package_defined_in
504 . " and cannot be created again in "
508 $name =~ /^[\w:\.]+$/
509 or die qq{$name contains invalid characters for a type name.}
510 . qq{ Names can contain alphanumeric character, ":", and "."\n};
515 package_defined_in => $pkg_defined_in,
517 ( $check ? ( constraint => $check ) : () ),
518 ( $message ? ( message => $message ) : () ),
519 ( $optimized ? ( optimized => $optimized ) : () ),
528 : find_or_create_isa_type_constraint($parent)
530 $constraint = $parent->create_child_type(%opts);
533 $constraint = Moose::Meta::TypeConstraint->new(%opts);
536 $REGISTRY->add_type_constraint($constraint)
542 sub _install_type_coercions ($$) {
543 my ( $type_name, $coercion_map ) = @_;
544 my $type = find_type_constraint($type_name);
546 || __PACKAGE__->_throw_error(
547 "Cannot find type '$type_name', perhaps you forgot to load it");
548 if ( $type->has_coercion ) {
549 $type->coercion->add_type_coercions(@$coercion_map);
552 my $type_coercion = Moose::Meta::TypeCoercion->new(
553 type_coercion_map => $coercion_map,
554 type_constraint => $type
556 $type->coercion($type_coercion);
560 ## --------------------------------------------------------
561 ## type notation parsing ...
562 ## --------------------------------------------------------
566 # All I have to say is mugwump++ cause I know
567 # do not even have enough regexp-fu to be able
568 # to have written this (I can only barely
569 # understand it as it is)
574 my $valid_chars = qr{[\w:\.]};
575 my $type_atom = qr{ (?>$valid_chars+) }x;
576 my $ws = qr{ (?>\s*) }x;
580 my $type = qr{ $type_atom (?: \[ $ws (??{$any}) $ws \] )? }x;
581 my $type_capture_parts
582 = qr{ ($type_atom) (?: \[ $ws ((??{$any})) $ws \] )? }x;
583 my $type_with_parameter
584 = qr{ $type_atom \[ $ws (??{$any}) $ws \] }x;
586 my $op_union = qr{ $ws \| $ws }x;
587 my $union = qr{ $type (?> (?: $op_union $type )+ ) }x;
589 $any = qr{ $type | $union }x;
591 sub _parse_parameterized_type_constraint {
592 { no warnings 'void'; $any; } # force capture of interpolated lexical
593 $_[0] =~ m{ $type_capture_parts }x;
597 sub _detect_parameterized_type_constraint {
598 { no warnings 'void'; $any; } # force capture of interpolated lexical
599 $_[0] =~ m{ ^ $type_with_parameter $ }x;
602 sub _parse_type_constraint_union {
603 { no warnings 'void'; $any; } # force capture of interpolated lexical
606 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
609 ( pos($given) eq length($given) )
610 || __PACKAGE__->_throw_error( "'$given' didn't parse (parse-pos="
618 sub _detect_type_constraint_union {
619 { no warnings 'void'; $any; } # force capture of interpolated lexical
620 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
624 ## --------------------------------------------------------
625 # define some basic built-in types
626 ## --------------------------------------------------------
628 # By making these classes immutable before creating all the types we
629 # below, we avoid repeatedly calling the slow MOP-based accessors.
631 inline_constructor => 1,
632 constructor_name => "_new",
634 # these are Class::MOP accessors, so they need inlining
635 inline_accessors => 1
636 ) for grep { $_->is_mutable }
637 map { Class::MOP::class_of($_) }
639 Moose::Meta::TypeConstraint
640 Moose::Meta::TypeConstraint::Union
641 Moose::Meta::TypeConstraint::Parameterized
642 Moose::Meta::TypeConstraint::Parameterizable
643 Moose::Meta::TypeConstraint::Class
644 Moose::Meta::TypeConstraint::Role
645 Moose::Meta::TypeConstraint::Enum
646 Moose::Meta::TypeConstraint::DuckType
647 Moose::Meta::TypeConstraint::Registry
650 type 'Any' => where {1}; # meta-type including all
651 subtype 'Item' => as 'Any'; # base-type
653 subtype 'Undef' => as 'Item' => where { !defined($_) };
654 subtype 'Defined' => as 'Item' => where { defined($_) };
656 subtype 'Bool' => as 'Item' =>
657 where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
659 subtype 'Value' => as 'Defined' => where { !ref($_) } =>
660 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
662 subtype 'Ref' => as 'Defined' => where { ref($_) } =>
663 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
665 subtype 'Str' => as 'Value' => where { ref(\$_) eq 'SCALAR' } =>
666 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
668 subtype 'Num' => as 'Str' =>
669 where { Scalar::Util::looks_like_number($_) } =>
670 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
672 subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } =>
673 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
675 subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
676 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
677 subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } =>
679 \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
680 subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
681 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
684 # scalar filehandles are GLOB refs,
685 # but a GLOB ref is not always a filehandle
686 subtype 'FileHandle' => as 'GlobRef' => where {
687 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
689 \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
692 # blessed(qr/.../) returns true,.. how odd
693 subtype 'Object' => as 'Ref' =>
694 where { blessed($_) && blessed($_) ne 'Regexp' } =>
695 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
697 # This type is deprecated.
698 subtype 'Role' => as 'Object' => where { $_->can('does') } =>
699 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
701 my $_class_name_checker = sub { };
703 subtype 'ClassName' => as 'Str' =>
704 where { Class::MOP::is_class_loaded($_) } => optimize_as
705 \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
707 subtype 'RoleName' => as 'ClassName' => where {
708 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
710 \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
712 ## --------------------------------------------------------
713 # parameterizable types ...
715 $REGISTRY->add_type_constraint(
716 Moose::Meta::TypeConstraint::Parameterizable->new(
718 package_defined_in => __PACKAGE__,
719 parent => find_type_constraint('Ref'),
720 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
722 \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef,
723 constraint_generator => sub {
724 my $type_parameter = shift;
725 my $check = $type_parameter->_compiled_type_constraint;
727 return $check->(${ $_ });
733 $REGISTRY->add_type_constraint(
734 Moose::Meta::TypeConstraint::Parameterizable->new(
736 package_defined_in => __PACKAGE__,
737 parent => find_type_constraint('Ref'),
738 constraint => sub { ref($_) eq 'ARRAY' },
740 \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
741 constraint_generator => sub {
742 my $type_parameter = shift;
743 my $check = $type_parameter->_compiled_type_constraint;
745 foreach my $x (@$_) {
746 ( $check->($x) ) || return;
754 $REGISTRY->add_type_constraint(
755 Moose::Meta::TypeConstraint::Parameterizable->new(
757 package_defined_in => __PACKAGE__,
758 parent => find_type_constraint('Ref'),
759 constraint => sub { ref($_) eq 'HASH' },
761 \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
762 constraint_generator => sub {
763 my $type_parameter = shift;
764 my $check = $type_parameter->_compiled_type_constraint;
766 foreach my $x ( values %$_ ) {
767 ( $check->($x) ) || return;
775 $REGISTRY->add_type_constraint(
776 Moose::Meta::TypeConstraint::Parameterizable->new(
778 package_defined_in => __PACKAGE__,
779 parent => find_type_constraint('Item'),
780 constraint => sub {1},
781 constraint_generator => sub {
782 my $type_parameter = shift;
783 my $check = $type_parameter->_compiled_type_constraint;
785 return 1 if not( defined($_) ) || $check->($_);
792 my @PARAMETERIZABLE_TYPES
793 = map { $REGISTRY->get_type_constraint($_) } qw[ScalarRef ArrayRef HashRef Maybe];
795 sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
797 sub add_parameterizable_type {
800 && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
801 || __PACKAGE__->_throw_error(
802 "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
804 push @PARAMETERIZABLE_TYPES => $type;
807 ## --------------------------------------------------------
808 # end of built-in types ...
809 ## --------------------------------------------------------
812 my @BUILTINS = list_all_type_constraints();
813 sub list_all_builtin_type_constraints {@BUILTINS}
820 goto &Moose::throw_error;
831 Moose::Util::TypeConstraints - Type constraint system for Moose
835 use Moose::Util::TypeConstraints;
841 subtype 'NaturalLessThanTen'
844 => message { "This number ($_) is not less than ten!" };
850 enum 'RGBColors' => qw(red green blue);
852 no Moose::Util::TypeConstraints;
856 This module provides Moose with the ability to create custom type
857 constraints to be used in attribute definition.
859 =head2 Important Caveat
861 This is B<NOT> a type system for Perl 5. These are type constraints,
862 and they are not used by Moose unless you tell it to. No type
863 inference is performed, expressions are not typed, etc. etc. etc.
865 A type constraint is at heart a small "check if a value is valid"
866 function. A constraint can be associated with an attribute. This
867 simplifies parameter validation, and makes your code clearer to read,
868 because you can refer to constraints by name.
870 =head2 Slightly Less Important Caveat
872 It is B<always> a good idea to quote your type names.
874 This prevents Perl from trying to execute the call as an indirect
875 object call. This can be an issue when you have a subtype with the
876 same name as a valid class.
880 subtype DateTime => as Object => where { $_->isa('DateTime') };
882 will I<just work>, while this:
885 subtype DateTime => as Object => where { $_->isa('DateTime') };
887 will fail silently and cause many headaches. The simple way to solve
888 this, as well as future proof your subtypes from classes which have
889 yet to have been created, is to quote the type name:
892 subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
894 =head2 Default Type Constraints
896 This module also provides a simple hierarchy for Perl 5 types, here is
897 that hierarchy represented visually.
921 B<NOTE:> Any type followed by a type parameter C<[`a]> can be
922 parameterized, this means you can say:
924 ArrayRef[Int] # an array of integers
925 HashRef[CodeRef] # a hash of str to CODE ref mappings
926 ScalarRef[Int] # a reference to an integer
927 Maybe[Str] # value may be a string, may be undefined
929 If Moose finds a name in brackets that it does not recognize as an
930 existing type, it assumes that this is a class name, for example
931 C<ArrayRef[DateTime]>.
933 B<NOTE:> Unless you parameterize a type, then it is invalid to include
934 the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
935 name, I<not> as a parameterization of C<ArrayRef>.
937 B<NOTE:> The C<Undef> type constraint for the most part works
938 correctly now, but edge cases may still exist, please use it
941 B<NOTE:> The C<ClassName> type constraint does a complex package
942 existence check. This means that your class B<must> be loaded for this
943 type constraint to pass.
945 B<NOTE:> The C<RoleName> constraint checks a string is a I<package
946 name> which is a role, like C<'MyApp::Role::Comparable'>.
948 =head2 Type Constraint Naming
950 Type name declared via this module can only contain alphanumeric
951 characters, colons (:), and periods (.).
953 Since the types created by this module are global, it is suggested
954 that you namespace your types just as you would namespace your
955 modules. So instead of creating a I<Color> type for your
956 B<My::Graphics> module, you would call the type
957 I<My::Graphics::Types::Color> instead.
959 =head2 Use with Other Constraint Modules
961 This module can play nicely with other constraint modules with some
962 slight tweaking. The C<where> clause in types is expected to be a
963 C<CODE> reference which checks it's first argument and returns a
964 boolean. Since most constraint modules work in a similar way, it
965 should be simple to adapt them to work with Moose.
967 For instance, this is how you could use it with
968 L<Declare::Constraints::Simple> to declare a completely new type.
970 type 'HashOfArrayOfObjects',
974 -values => IsArrayRef(IsObject)
978 For more examples see the F<t/200_examples/004_example_w_DCS.t> test
981 Here is an example of using L<Test::Deep> and it's non-test
982 related C<eq_deeply> function.
984 type 'ArrayOfHashOfBarsAndRandomNumbers'
987 array_each(subhashof({
989 random_number => ignore()
993 For a complete example see the
994 F<t/200_examples/005_example_w_TestDeep.t> test file.
998 =head2 Type Constraint Constructors
1000 The following functions are used to create type constraints. They
1001 will also register the type constraints your create in a global
1002 registry that is used to look types up by name.
1004 See the L</SYNOPSIS> for an example of how to use these.
1008 =item B<< subtype 'Name' => as 'Parent' => where { } ... >>
1010 This creates a named subtype.
1012 If you provide a parent that Moose does not recognize, it will
1013 automatically create a new class type constraint for this name.
1015 When creating a named type, the C<subtype> function should either be
1016 called with the sugar helpers (C<where>, C<message>, etc), or with a
1017 name and a hashref of parameters:
1019 subtype( 'Foo', { where => ..., message => ... } );
1021 The valid hashref keys are C<as> (the parent), C<where>, C<message>,
1024 =item B<< subtype as 'Parent' => where { } ... >>
1026 This creates an unnamed subtype and will return the type
1027 constraint meta-object, which will be an instance of
1028 L<Moose::Meta::TypeConstraint>.
1030 When creating an anonymous type, the C<subtype> function should either
1031 be called with the sugar helpers (C<where>, C<message>, etc), or with
1032 just a hashref of parameters:
1034 subtype( { where => ..., message => ... } );
1036 =item B<class_type ($class, ?$options)>
1038 Creates a new subtype of C<Object> with the name C<$class> and the
1039 metaclass L<Moose::Meta::TypeConstraint::Class>.
1041 =item B<role_type ($role, ?$options)>
1043 Creates a C<Role> type constraint with the name C<$role> and the
1044 metaclass L<Moose::Meta::TypeConstraint::Role>.
1046 =item B<maybe_type ($type)>
1048 Creates a type constraint for either C<undef> or something of the
1051 =item B<duck_type ($name, \@methods)>
1053 This will create a subtype of Object and test to make sure the value
1054 C<can()> do the methods in C<\@methods>.
1056 This is intended as an easy way to accept non-Moose objects that
1057 provide a certain interface. If you're using Moose classes, we
1058 recommend that you use a C<requires>-only Role instead.
1060 =item B<duck_type (\@methods)>
1062 If passed an ARRAY reference as the only parameter instead of the
1063 C<$name>, C<\@methods> pair, this will create an unnamed duck type.
1064 This can be used in an attribute definition like so:
1068 isa => duck_type( [qw( get_set )] ),
1071 =item B<enum ($name, \@values)>
1073 This will create a basic subtype for a given set of strings.
1074 The resulting constraint will be a subtype of C<Str> and
1075 will match any of the items in C<\@values>. It is case sensitive.
1076 See the L</SYNOPSIS> for a simple example.
1078 B<NOTE:> This is not a true proper enum type, it is simply
1079 a convenient constraint builder.
1081 =item B<enum (\@values)>
1083 If passed an ARRAY reference as the only parameter instead of the
1084 C<$name>, C<\@values> pair, this will create an unnamed enum. This
1085 can then be used in an attribute definition like so:
1087 has 'sort_order' => (
1089 isa => enum([qw[ ascending descending ]]),
1092 =item B<as 'Parent'>
1094 This is just sugar for the type constraint construction syntax.
1096 It takes a single argument, which is the name of a parent type.
1098 =item B<where { ... }>
1100 This is just sugar for the type constraint construction syntax.
1102 It takes a subroutine reference as an argument. When the type
1103 constraint is tested, the reference is run with the value to be tested
1104 in C<$_>. This reference should return true or false to indicate
1105 whether or not the constraint check passed.
1107 =item B<message { ... }>
1109 This is just sugar for the type constraint construction syntax.
1111 It takes a subroutine reference as an argument. When the type
1112 constraint fails, then the code block is run with the value provided
1113 in C<$_>. This reference should return a string, which will be used in
1114 the text of the exception thrown.
1116 =item B<optimize_as { ... }>
1118 This can be used to define a "hand optimized" version of your
1119 type constraint which can be used to avoid traversing a subtype
1120 constraint hierarchy.
1122 B<NOTE:> You should only use this if you know what you are doing,
1123 all the built in types use this, so your subtypes (assuming they
1124 are shallow) will not likely need to use this.
1126 =item B<< type 'Name' => where { } ... >>
1128 This creates a base type, which has no parent.
1130 The C<type> function should either be called with the sugar helpers
1131 (C<where>, C<message>, etc), or with a name and a hashref of
1134 type( 'Foo', { where => ..., message => ... } );
1136 The valid hashref keys are C<where>, C<message>, and C<optimize_as>.
1140 =head2 Type Constraint Utilities
1144 =item B<< match_on_type $value => ( $type => \&action, ... ?\&default ) >>
1146 This is a utility function for doing simple type based dispatching similar to
1147 match/case in OCaml and case/of in Haskell. It is not as featureful as those
1148 languages, nor does not it support any kind of automatic destructuring
1149 bind. Here is a simple Perl pretty printer dispatching over the core Moose
1154 match_on_type $x => (
1159 join ", " => map { $_ . ' => ' . ppprint( $hash->{$_} ) }
1165 '[ ' . ( join ", " => map { ppprint($_) } @$array ) . ' ]';
1167 CodeRef => sub {'sub { ... }'},
1168 RegexpRef => sub { 'qr/' . $_ . '/' },
1169 GlobRef => sub { '*' . B::svref_2object($_)->NAME },
1170 Object => sub { $_->can('to_string') ? $_->to_string : $_ },
1171 ScalarRef => sub { '\\' . ppprint( ${$_} ) },
1173 Str => sub { '"' . $_ . '"' },
1174 Undef => sub {'undef'},
1175 => sub { die "I don't know what $_ is" }
1179 Or a simple JSON serializer:
1183 match_on_type $x => (
1189 map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
1195 '[ ' . ( join ", " => map { to_json($_) } @$array ) . ' ]';
1198 Str => sub { '"' . $_ . '"' },
1199 Undef => sub {'null'},
1200 => sub { die "$_ is not acceptable json type" }
1204 The matcher is done by mapping a C<$type> to an C<\&action>. The C<$type> can
1205 be either a string type or a L<Moose::Meta::TypeConstraint> object, and
1206 C<\&action> is a subroutine reference. This function will dispatch on the
1207 first match for C<$value>. It is possible to have a catch-all by providing an
1208 additional subroutine reference as the final argument to C<match_on_type>.
1212 =head2 Type Coercion Constructors
1214 You can define coercions for type constraints, which allow you to
1215 automatically transform values to something valid for the type
1216 constraint. If you ask your accessor to coerce, then Moose will run
1217 the type-coercion code first, followed by the type constraint
1218 check. This feature should be used carefully as it is very powerful
1219 and could easily take off a limb if you are not careful.
1221 See the L</SYNOPSIS> for an example of how to use these.
1225 =item B<< coerce 'Name' => from 'OtherName' => via { ... } >>
1227 This defines a coercion from one type to another. The C<Name> argument
1228 is the type you are coercing I<to>.
1230 =item B<from 'OtherName'>
1232 This is just sugar for the type coercion construction syntax.
1234 It takes a single type name (or type object), which is the type being
1237 =item B<via { ... }>
1239 This is just sugar for the type coercion construction syntax.
1241 It takes a subroutine reference. This reference will be called with
1242 the value to be coerced in C<$_>. It is expected to return a new value
1243 of the proper type for the coercion.
1247 =head2 Creating and Finding Type Constraints
1249 These are additional functions for creating and finding type
1250 constraints. Most of these functions are not available for
1251 importing. The ones that are importable as specified.
1255 =item B<find_type_constraint($type_name)>
1257 This function can be used to locate the L<Moose::Meta::TypeConstraint>
1258 object for a named type.
1260 This function is importable.
1262 =item B<register_type_constraint($type_object)>
1264 This function will register a L<Moose::Meta::TypeConstraint> with the
1265 global type registry.
1267 This function is importable.
1269 =item B<normalize_type_constraint_name($type_constraint_name)>
1271 This method takes a type constraint name and returns the normalized
1272 form. This removes any whitespace in the string.
1274 =item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
1276 This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1277 or a list of names. It returns a new
1278 L<Moose::Meta::TypeConstraint::Union> object.
1280 =item B<create_parameterized_type_constraint($type_name)>
1282 Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1283 this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1284 object. The C<BaseType> must exist already exist as a parameterizable
1287 =item B<create_class_type_constraint($class, $options)>
1289 Given a class name this function will create a new
1290 L<Moose::Meta::TypeConstraint::Class> object for that class name.
1292 The C<$options> is a hash reference that will be passed to the
1293 L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
1295 =item B<create_role_type_constraint($role, $options)>
1297 Given a role name this function will create a new
1298 L<Moose::Meta::TypeConstraint::Role> object for that role name.
1300 The C<$options> is a hash reference that will be passed to the
1301 L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
1303 =item B<create_enum_type_constraint($name, $values)>
1305 Given a enum name this function will create a new
1306 L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1308 =item B<create_duck_type_constraint($name, $methods)>
1310 Given a duck type name this function will create a new
1311 L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
1313 =item B<find_or_parse_type_constraint($type_name)>
1315 Given a type name, this first attempts to find a matching constraint
1316 in the global registry.
1318 If the type name is a union or parameterized type, it will create a
1319 new object of the appropriate, but if given a "regular" type that does
1320 not yet exist, it simply returns false.
1322 When given a union or parameterized type, the member or base type must
1325 If it creates a new union or parameterized type, it will add it to the
1328 =item B<find_or_create_isa_type_constraint($type_name)>
1330 =item B<find_or_create_does_type_constraint($type_name)>
1332 These functions will first call C<find_or_parse_type_constraint>. If
1333 that function does not return a type, a new anonymous type object will
1336 The C<isa> variant will use C<create_class_type_constraint> and the
1337 C<does> variant will use C<create_role_type_constraint>.
1339 =item B<get_type_constraint_registry>
1341 Returns the L<Moose::Meta::TypeConstraint::Registry> object which
1342 keeps track of all type constraints.
1344 =item B<list_all_type_constraints>
1346 This will return a list of type constraint names in the global
1347 registry. You can then fetch the actual type object using
1348 C<find_type_constraint($type_name)>.
1350 =item B<list_all_builtin_type_constraints>
1352 This will return a list of builtin type constraints, meaning those
1353 which are defined in this module. See the L<Default Type Constraints>
1354 section for a complete list.
1356 =item B<export_type_constraints_as_functions>
1358 This will export all the current type constraints as functions into
1359 the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1360 mostly used for testing, but it might prove useful to others.
1362 =item B<get_all_parameterizable_types>
1364 This returns all the parameterizable types that have been registered,
1365 as a list of type objects.
1367 =item B<add_parameterizable_type($type)>
1369 Adds C<$type> to the list of parameterizable types
1375 See L<Moose/BUGS> for details on reporting bugs.
1379 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1381 =head1 COPYRIGHT AND LICENSE
1383 Copyright 2006-2010 by Infinity Interactive, Inc.
1385 L<http://www.iinteractive.com>
1387 This library is free software; you can redistribute it and/or modify
1388 it under the same terms as Perl itself.