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
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 return _create_type_constraint( $_[0], undef, $_[1] );
284 my %p = map { %{$_} } @_;
286 return _create_type_constraint(
287 $name, undef, $p{where}, $p{message},
294 # crazy back-compat code for being called without sugar ...
296 # subtype 'Parent', sub { where };
297 if ( scalar @_ == 2 && ( reftype( $_[1] ) || '' ) eq 'CODE' ) {
298 return _create_type_constraint( undef, @_ );
301 # subtype 'Parent', sub { where }, sub { message };
302 # subtype 'Parent', sub { where }, sub { message }, sub { optimized };
303 if ( scalar @_ >= 3 && all { ( reftype($_) || '' ) eq 'CODE' }
305 return _create_type_constraint( undef, @_ );
308 # subtype 'Name', 'Parent', ...
309 if ( scalar @_ >= 2 && all { !ref } @_[ 0, 1 ] ) {
310 return _create_type_constraint(@_);
313 if ( @_ == 1 && !ref $_[0] ) {
314 __PACKAGE__->_throw_error(
315 'A subtype cannot consist solely of a name, it must have a parent'
319 # The blessed check is mostly to accommodate MooseX::Types, which
320 # uses an object which overloads stringification as a type name.
321 my $name = ref $_[0] && !blessed $_[0] ? undef : shift;
323 my %p = map { %{$_} } @_;
325 # subtype Str => where { ... };
326 if ( !exists $p{as} ) {
331 return _create_type_constraint(
332 $name, $p{as}, $p{where}, $p{message},
338 register_type_constraint(
339 create_class_type_constraint(
341 ( defined( $_[1] ) ? $_[1] : () ),
346 sub role_type ($;$) {
347 register_type_constraint(
348 create_role_type_constraint(
350 ( defined( $_[1] ) ? $_[1] : () ),
356 my ($type_parameter) = @_;
358 register_type_constraint(
359 $REGISTRY->get_type_constraint('Maybe')->parameterize($type_parameter)
364 my ( $type_name, @methods ) = @_;
365 if ( ref $type_name eq 'ARRAY' && !@methods ) {
366 @methods = @$type_name;
369 if ( @methods == 1 && ref $methods[0] eq 'ARRAY' ) {
370 @methods = @{ $methods[0] };
373 register_type_constraint(
374 create_duck_type_constraint(
382 my ( $type_name, @coercion_map ) = @_;
383 _install_type_coercions( $type_name, \@coercion_map );
386 # The trick of returning @_ lets us avoid having to specify a
387 # prototype. Perl will parse this:
395 # subtype( 'Foo', as( 'Str', where { ... } ) );
397 # If as() returns all it's extra arguments, this just works, and
398 # preserves backwards compatibility.
399 sub as { { as => shift }, @_ }
400 sub where (&) { { where => $_[0] } }
401 sub message (&) { { message => $_[0] } }
402 sub optimize_as (&) { { optimize_as => $_[0] } }
405 sub via (&) { $_[0] }
408 my ( $type_name, @values ) = @_;
411 # if only an array-ref is passed then
412 # you get an anon-enum
414 if ( ref $type_name eq 'ARRAY' && !@values ) {
415 @values = @$type_name;
418 if ( @values == 1 && ref $values[0] eq 'ARRAY' ) {
419 @values = @{ $values[0] };
421 ( scalar @values >= 2 )
422 || __PACKAGE__->_throw_error(
423 "You must have at least two values to enumerate through");
424 my %valid = map { $_ => 1 } @values;
426 register_type_constraint(
427 create_enum_type_constraint(
434 sub create_enum_type_constraint {
435 my ( $type_name, $values ) = @_;
437 Moose::Meta::TypeConstraint::Enum->new(
438 name => $type_name || '__ANON__',
443 sub create_duck_type_constraint {
444 my ( $type_name, $methods ) = @_;
446 Moose::Meta::TypeConstraint::DuckType->new(
447 name => $type_name || '__ANON__',
453 my ($to_match, @cases) = @_;
455 if (@cases % 2 != 0) {
456 $default = pop @cases;
457 (ref $default eq 'CODE')
458 || __PACKAGE__->_throw_error("Default case must be a CODE ref, not $default");
461 my ($type, $action) = splice @cases, 0, 2;
463 unless (blessed $type && $type->isa('Moose::Meta::TypeConstraint')) {
464 $type = find_or_parse_type_constraint($type)
465 || __PACKAGE__->_throw_error("Cannot find or parse the type '$type'")
468 (ref $action eq 'CODE')
469 || __PACKAGE__->_throw_error("Match action must be a CODE ref, not $action");
471 if ($type->check($to_match)) {
472 local $_ = $to_match;
473 return $action->($to_match);
477 || __PACKAGE__->_throw_error("No cases matched for $to_match");
479 local $_ = $to_match;
480 return $default->($to_match);
485 ## --------------------------------------------------------
486 ## desugaring functions ...
487 ## --------------------------------------------------------
489 sub _create_type_constraint ($$$;$$) {
494 my $optimized = shift;
496 my $pkg_defined_in = scalar( caller(1) );
498 if ( defined $name ) {
499 my $type = $REGISTRY->get_type_constraint($name);
501 ( $type->_package_defined_in eq $pkg_defined_in )
503 "The type constraint '$name' has already been created in "
504 . $type->_package_defined_in
505 . " and cannot be created again in "
509 $name =~ /^[\w:\.]+$/
510 or die qq{$name contains invalid characters for a type name.}
511 . qq{ Names can contain alphanumeric character, ":", and "."\n};
516 package_defined_in => $pkg_defined_in,
518 ( $check ? ( constraint => $check ) : () ),
519 ( $message ? ( message => $message ) : () ),
520 ( $optimized ? ( optimized => $optimized ) : () ),
529 : find_or_create_isa_type_constraint($parent)
531 $constraint = $parent->create_child_type(%opts);
534 $constraint = Moose::Meta::TypeConstraint->new(%opts);
537 $REGISTRY->add_type_constraint($constraint)
543 sub _install_type_coercions ($$) {
544 my ( $type_name, $coercion_map ) = @_;
545 my $type = find_type_constraint($type_name);
547 || __PACKAGE__->_throw_error(
548 "Cannot find type '$type_name', perhaps you forgot to load it");
549 if ( $type->has_coercion ) {
550 $type->coercion->add_type_coercions(@$coercion_map);
553 my $type_coercion = Moose::Meta::TypeCoercion->new(
554 type_coercion_map => $coercion_map,
555 type_constraint => $type
557 $type->coercion($type_coercion);
561 ## --------------------------------------------------------
562 ## type notation parsing ...
563 ## --------------------------------------------------------
567 # All I have to say is mugwump++ cause I know
568 # do not even have enough regexp-fu to be able
569 # to have written this (I can only barely
570 # understand it as it is)
575 my $valid_chars = qr{[\w:\.]};
576 my $type_atom = qr{ $valid_chars+ };
580 my $type = qr{ $valid_chars+ (?: \[ \s* (??{$any}) \s* \] )? }x;
581 my $type_capture_parts
582 = qr{ ($valid_chars+) (?: \[ \s* ((??{$any})) \s* \] )? }x;
583 my $type_with_parameter
584 = qr{ $valid_chars+ \[ \s* (??{$any}) \s* \] }x;
586 my $op_union = qr{ \s* \| \s* }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 'ScalarRef' => as 'Ref' => where { ref($_) eq 'SCALAR' } =>
677 \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef;
678 subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
679 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
680 subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } =>
682 \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
683 subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
684 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
687 # scalar filehandles are GLOB refs,
688 # but a GLOB ref is not always a filehandle
689 subtype 'FileHandle' => as 'GlobRef' => where {
690 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
692 \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
695 # blessed(qr/.../) returns true,.. how odd
696 subtype 'Object' => as 'Ref' =>
697 where { blessed($_) && blessed($_) ne 'Regexp' } =>
698 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
700 # This type is deprecated.
701 subtype 'Role' => as 'Object' => where { $_->can('does') } =>
702 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
704 my $_class_name_checker = sub { };
706 subtype 'ClassName' => as 'Str' =>
707 where { Class::MOP::is_class_loaded($_) } => optimize_as
708 \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
710 subtype 'RoleName' => as 'ClassName' => where {
711 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
713 \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
715 ## --------------------------------------------------------
716 # parameterizable types ...
718 $REGISTRY->add_type_constraint(
719 Moose::Meta::TypeConstraint::Parameterizable->new(
721 package_defined_in => __PACKAGE__,
722 parent => find_type_constraint('Ref'),
723 constraint => sub { ref($_) eq 'ARRAY' },
725 \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
726 constraint_generator => sub {
727 my $type_parameter = shift;
728 my $check = $type_parameter->_compiled_type_constraint;
730 foreach my $x (@$_) {
731 ( $check->($x) ) || return;
739 $REGISTRY->add_type_constraint(
740 Moose::Meta::TypeConstraint::Parameterizable->new(
742 package_defined_in => __PACKAGE__,
743 parent => find_type_constraint('Ref'),
744 constraint => sub { ref($_) eq 'HASH' },
746 \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
747 constraint_generator => sub {
748 my $type_parameter = shift;
749 my $check = $type_parameter->_compiled_type_constraint;
751 foreach my $x ( values %$_ ) {
752 ( $check->($x) ) || return;
760 $REGISTRY->add_type_constraint(
761 Moose::Meta::TypeConstraint::Parameterizable->new(
763 package_defined_in => __PACKAGE__,
764 parent => find_type_constraint('Item'),
765 constraint => sub {1},
766 constraint_generator => sub {
767 my $type_parameter = shift;
768 my $check = $type_parameter->_compiled_type_constraint;
770 return 1 if not( defined($_) ) || $check->($_);
777 my @PARAMETERIZABLE_TYPES
778 = map { $REGISTRY->get_type_constraint($_) } qw[ArrayRef HashRef Maybe];
780 sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
782 sub add_parameterizable_type {
785 && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
786 || __PACKAGE__->_throw_error(
787 "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
789 push @PARAMETERIZABLE_TYPES => $type;
792 ## --------------------------------------------------------
793 # end of built-in types ...
794 ## --------------------------------------------------------
797 my @BUILTINS = list_all_type_constraints();
798 sub list_all_builtin_type_constraints {@BUILTINS}
805 goto &Moose::throw_error;
816 Moose::Util::TypeConstraints - Type constraint system for Moose
820 use Moose::Util::TypeConstraints;
826 subtype 'NaturalLessThanTen'
829 => message { "This number ($_) is not less than ten!" };
835 enum 'RGBColors' => qw(red green blue);
837 no Moose::Util::TypeConstraints;
841 This module provides Moose with the ability to create custom type
842 constraints to be used in attribute definition.
844 =head2 Important Caveat
846 This is B<NOT> a type system for Perl 5. These are type constraints,
847 and they are not used by Moose unless you tell it to. No type
848 inference is performed, expressions are not typed, etc. etc. etc.
850 A type constraint is at heart a small "check if a value is valid"
851 function. A constraint can be associated with an attribute. This
852 simplifies parameter validation, and makes your code clearer to read,
853 because you can refer to constraints by name.
855 =head2 Slightly Less Important Caveat
857 It is B<always> a good idea to quote your type names.
859 This prevents Perl from trying to execute the call as an indirect
860 object call. This can be an issue when you have a subtype with the
861 same name as a valid class.
865 subtype DateTime => as Object => where { $_->isa('DateTime') };
867 will I<just work>, while this:
870 subtype DateTime => as Object => where { $_->isa('DateTime') };
872 will fail silently and cause many headaches. The simple way to solve
873 this, as well as future proof your subtypes from classes which have
874 yet to have been created, is to quote the type name:
877 subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
879 =head2 Default Type Constraints
881 This module also provides a simple hierarchy for Perl 5 types, here is
882 that hierarchy represented visually.
906 B<NOTE:> Any type followed by a type parameter C<[`a]> can be
907 parameterized, this means you can say:
909 ArrayRef[Int] # an array of integers
910 HashRef[CodeRef] # a hash of str to CODE ref mappings
911 Maybe[Str] # value may be a string, may be undefined
913 If Moose finds a name in brackets that it does not recognize as an
914 existing type, it assumes that this is a class name, for example
915 C<ArrayRef[DateTime]>.
917 B<NOTE:> Unless you parameterize a type, then it is invalid to include
918 the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
919 name, I<not> as a parameterization of C<ArrayRef>.
921 B<NOTE:> The C<Undef> type constraint for the most part works
922 correctly now, but edge cases may still exist, please use it
925 B<NOTE:> The C<ClassName> type constraint does a complex package
926 existence check. This means that your class B<must> be loaded for this
927 type constraint to pass.
929 B<NOTE:> The C<RoleName> constraint checks a string is a I<package
930 name> which is a role, like C<'MyApp::Role::Comparable'>.
932 =head2 Type Constraint Naming
934 Type name declared via this module can only contain alphanumeric
935 characters, colons (:), and periods (.).
937 Since the types created by this module are global, it is suggested
938 that you namespace your types just as you would namespace your
939 modules. So instead of creating a I<Color> type for your
940 B<My::Graphics> module, you would call the type
941 I<My::Graphics::Types::Color> instead.
943 =head2 Use with Other Constraint Modules
945 This module can play nicely with other constraint modules with some
946 slight tweaking. The C<where> clause in types is expected to be a
947 C<CODE> reference which checks it's first argument and returns a
948 boolean. Since most constraint modules work in a similar way, it
949 should be simple to adapt them to work with Moose.
951 For instance, this is how you could use it with
952 L<Declare::Constraints::Simple> to declare a completely new type.
954 type 'HashOfArrayOfObjects',
958 -values => IsArrayRef(IsObject)
962 For more examples see the F<t/200_examples/004_example_w_DCS.t> test
965 Here is an example of using L<Test::Deep> and it's non-test
966 related C<eq_deeply> function.
968 type 'ArrayOfHashOfBarsAndRandomNumbers'
971 array_each(subhashof({
973 random_number => ignore()
977 For a complete example see the
978 F<t/200_examples/005_example_w_TestDeep.t> test file.
982 =head2 Type Constraint Constructors
984 The following functions are used to create type constraints. They
985 will also register the type constraints your create in a global
986 registry that is used to look types up by name.
988 See the L<SYNOPSIS> for an example of how to use these.
992 =item B<< subtype 'Name' => as 'Parent' => where { } ... >>
994 This creates a named subtype.
996 If you provide a parent that Moose does not recognize, it will
997 automatically create a new class type constraint for this name.
999 When creating a named type, the C<subtype> function should either be
1000 called with the sugar helpers (C<where>, C<message>, etc), or with a
1001 name and a hashref of parameters:
1003 subtype( 'Foo', { where => ..., message => ... } );
1005 The valid hashref keys are C<as> (the parent), C<where>, C<message>,
1008 =item B<< subtype as 'Parent' => where { } ... >>
1010 This creates an unnamed subtype and will return the type
1011 constraint meta-object, which will be an instance of
1012 L<Moose::Meta::TypeConstraint>.
1014 When creating an anonymous type, the C<subtype> function should either
1015 be called with the sugar helpers (C<where>, C<message>, etc), or with
1016 just a hashref of parameters:
1018 subtype( { where => ..., message => ... } );
1020 =item B<class_type ($class, ?$options)>
1022 Creates a new subtype of C<Object> with the name C<$class> and the
1023 metaclass L<Moose::Meta::TypeConstraint::Class>.
1025 =item B<role_type ($role, ?$options)>
1027 Creates a C<Role> type constraint with the name C<$role> and the
1028 metaclass L<Moose::Meta::TypeConstraint::Role>.
1030 =item B<maybe_type ($type)>
1032 Creates a type constraint for either C<undef> or something of the
1035 =item B<duck_type ($name, \@methods)>
1037 This will create a subtype of Object and test to make sure the value
1038 C<can()> do the methods in C<\@methods>.
1040 This is intended as an easy way to accept non-Moose objects that
1041 provide a certain interface. If you're using Moose classes, we
1042 recommend that you use a C<requires>-only Role instead.
1044 =item B<duck_type (\@methods)>
1046 If passed an ARRAY reference as the only parameter instead of the
1047 C<$name>, C<\@methods> pair, this will create an unnamed duck type.
1048 This can be used in an attribute definition like so:
1052 isa => duck_type( [qw( get_set )] ),
1055 =item B<enum ($name, \@values)>
1057 This will create a basic subtype for a given set of strings.
1058 The resulting constraint will be a subtype of C<Str> and
1059 will match any of the items in C<\@values>. It is case sensitive.
1060 See the L<SYNOPSIS> for a simple example.
1062 B<NOTE:> This is not a true proper enum type, it is simply
1063 a convenient constraint builder.
1065 =item B<enum (\@values)>
1067 If passed an ARRAY reference as the only parameter instead of the
1068 C<$name>, C<\@values> pair, this will create an unnamed enum. This
1069 can then be used in an attribute definition like so:
1071 has 'sort_order' => (
1073 isa => enum([qw[ ascending descending ]]),
1076 =item B<as 'Parent'>
1078 This is just sugar for the type constraint construction syntax.
1080 It takes a single argument, which is the name of a parent type.
1082 =item B<where { ... }>
1084 This is just sugar for the type constraint construction syntax.
1086 It takes a subroutine reference as an argument. When the type
1087 constraint is tested, the reference is run with the value to be tested
1088 in C<$_>. This reference should return true or false to indicate
1089 whether or not the constraint check passed.
1091 =item B<message { ... }>
1093 This is just sugar for the type constraint construction syntax.
1095 It takes a subroutine reference as an argument. When the type
1096 constraint fails, then the code block is run with the value provided
1097 in C<$_>. This reference should return a string, which will be used in
1098 the text of the exception thrown.
1100 =item B<optimize_as { ... }>
1102 This can be used to define a "hand optimized" version of your
1103 type constraint which can be used to avoid traversing a subtype
1104 constraint hierarchy.
1106 B<NOTE:> You should only use this if you know what you are doing,
1107 all the built in types use this, so your subtypes (assuming they
1108 are shallow) will not likely need to use this.
1110 =item B<< type 'Name' => where { } ... >>
1112 This creates a base type, which has no parent.
1114 The C<type> function should either be called with the sugar helpers
1115 (C<where>, C<message>, etc), or with a name and a hashref of
1118 type( 'Foo', { where => ..., message => ... } );
1120 The valid hashref keys are C<where>, C<message>, and C<optimize_as>.
1124 =head2 Type Constraint Utilities
1128 =item B<< match_on_type $value => ( $type => \&action, ... ?\&default ) >>
1130 This is a utility function for doing simple type based dispatching similar to
1131 match/case in O'Caml and case/of in Haskell. It is not as featureful as those
1132 languages, nor does not it support any kind of automatic destructuring
1133 bind. Here is a simple Perl pretty printer dispatching over the core Moose
1138 match_on_type $x => (
1143 join ", " => map { $_ . ' => ' . ppprint( $hash->{$_} ) }
1149 '[ ' . ( join ", " => map { ppprint($_) } @$array ) . ' ]';
1151 CodeRef => sub {'sub { ... }'},
1152 RegexpRef => sub { 'qr/' . $_ . '/' },
1153 GlobRef => sub { '*' . B::svref_2object($_)->NAME },
1154 Object => sub { $_->can('to_string') ? $_->to_string : $_ },
1155 ScalarRef => sub { '\\' . ppprint( ${$_} ) },
1157 Str => sub { '"' . $_ . '"' },
1158 Undef => sub {'undef'},
1159 => sub { die "I don't know what $_ is" }
1163 Or a simple JSON serializer:
1167 match_on_type $x => (
1173 map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
1179 '[ ' . ( join ", " => map { to_json($_) } @$array ) . ' ]';
1182 Str => sub { '"' . $_ . '"' },
1183 Undef => sub {'null'},
1184 => sub { die "$_ is not acceptable json type" }
1188 The matcher is done by mapping a C<$type> to an C<\&action>. The C<$type> can
1189 be either a string type or a L<Moose::Meta::TypeConstraint> object, and
1190 C<\&action> is a subroutine reference. This function will dispatch on the
1191 first match for C<$value>. It is possible to have a catch-all by providing an
1192 additional subroutine reference as the final argument to C<match_on_type>.
1196 =head2 Type Coercion Constructors
1198 You can define coercions for type constraints, which allow you to
1199 automatically transform values to something valid for the type
1200 constraint. If you ask your accessor to coerce, then Moose will run
1201 the type-coercion code first, followed by the type constraint
1202 check. This feature should be used carefully as it is very powerful
1203 and could easily take off a limb if you are not careful.
1205 See the L<SYNOPSIS> for an example of how to use these.
1209 =item B<< coerce 'Name' => from 'OtherName' => via { ... } >>
1211 This defines a coercion from one type to another. The C<Name> argument
1212 is the type you are coercing I<to>.
1214 =item B<from 'OtherName'>
1216 This is just sugar for the type coercion construction syntax.
1218 It takes a single type name (or type object), which is the type being
1221 =item B<via { ... }>
1223 This is just sugar for the type coercion construction syntax.
1225 It takes a subroutine reference. This reference will be called with
1226 the value to be coerced in C<$_>. It is expected to return a new value
1227 of the proper type for the coercion.
1231 =head2 Creating and Finding Type Constraints
1233 These are additional functions for creating and finding type
1234 constraints. Most of these functions are not available for
1235 importing. The ones that are importable as specified.
1239 =item B<find_type_constraint($type_name)>
1241 This function can be used to locate the L<Moose::Meta::TypeConstraint>
1242 object for a named type.
1244 This function is importable.
1246 =item B<register_type_constraint($type_object)>
1248 This function will register a L<Moose::Meta::TypeConstraint> with the
1249 global type registry.
1251 This function is importable.
1253 =item B<normalize_type_constraint_name($type_constraint_name)>
1255 This method takes a type constraint name and returns the normalized
1256 form. This removes any whitespace in the string.
1258 =item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
1260 This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1261 or a list of names. It returns a new
1262 L<Moose::Meta::TypeConstraint::Union> object.
1264 =item B<create_parameterized_type_constraint($type_name)>
1266 Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1267 this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1268 object. The C<BaseType> must exist already exist as a parameterizable
1271 =item B<create_class_type_constraint($class, $options)>
1273 Given a class name this function will create a new
1274 L<Moose::Meta::TypeConstraint::Class> object for that class name.
1276 The C<$options> is a hash reference that will be passed to the
1277 L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
1279 =item B<create_role_type_constraint($role, $options)>
1281 Given a role name this function will create a new
1282 L<Moose::Meta::TypeConstraint::Role> object for that role name.
1284 The C<$options> is a hash reference that will be passed to the
1285 L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
1287 =item B<create_enum_type_constraint($name, $values)>
1289 Given a enum name this function will create a new
1290 L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1292 =item B<create_duck_type_constraint($name, $methods)>
1294 Given a duck type name this function will create a new
1295 L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
1297 =item B<find_or_parse_type_constraint($type_name)>
1299 Given a type name, this first attempts to find a matching constraint
1300 in the global registry.
1302 If the type name is a union or parameterized type, it will create a
1303 new object of the appropriate, but if given a "regular" type that does
1304 not yet exist, it simply returns false.
1306 When given a union or parameterized type, the member or base type must
1309 If it creates a new union or parameterized type, it will add it to the
1312 =item B<find_or_create_isa_type_constraint($type_name)>
1314 =item B<find_or_create_does_type_constraint($type_name)>
1316 These functions will first call C<find_or_parse_type_constraint>. If
1317 that function does not return a type, a new anonymous type object will
1320 The C<isa> variant will use C<create_class_type_constraint> and the
1321 C<does> variant will use C<create_role_type_constraint>.
1323 =item B<get_type_constraint_registry>
1325 Returns the L<Moose::Meta::TypeConstraint::Registry> object which
1326 keeps track of all type constraints.
1328 =item B<list_all_type_constraints>
1330 This will return a list of type constraint names in the global
1331 registry. You can then fetch the actual type object using
1332 C<find_type_constraint($type_name)>.
1334 =item B<list_all_builtin_type_constraints>
1336 This will return a list of builtin type constraints, meaning those
1337 which are defined in this module. See the L<Default Type Constraints>
1338 section for a complete list.
1340 =item B<export_type_constraints_as_functions>
1342 This will export all the current type constraints as functions into
1343 the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1344 mostly used for testing, but it might prove useful to others.
1346 =item B<get_all_parameterizable_types>
1348 This returns all the parameterizable types that have been registered,
1349 as a list of type objects.
1351 =item B<add_parameterizable_type($type)>
1353 Adds C<$type> to the list of parameterizable types
1359 All complex software has bugs lurking in it, and this module is no
1360 exception. If you find a bug please either email me, or add the bug
1365 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1367 =head1 COPYRIGHT AND LICENSE
1369 Copyright 2006-2009 by Infinity Interactive, Inc.
1371 L<http://www.iinteractive.com>
1373 This library is free software; you can redistribute it and/or modify
1374 it under the same terms as Perl itself.