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;
370 register_type_constraint(
371 create_duck_type_constraint(
379 my ( $type_name, @coercion_map ) = @_;
380 _install_type_coercions( $type_name, \@coercion_map );
383 # The trick of returning @_ lets us avoid having to specify a
384 # prototype. Perl will parse this:
392 # subtype( 'Foo', as( 'Str', where { ... } ) );
394 # If as() returns all it's extra arguments, this just works, and
395 # preserves backwards compatibility.
396 sub as { { as => shift }, @_ }
397 sub where (&) { { where => $_[0] } }
398 sub message (&) { { message => $_[0] } }
399 sub optimize_as (&) { { optimize_as => $_[0] } }
402 sub via (&) { $_[0] }
405 my ( $type_name, @values ) = @_;
408 # if only an array-ref is passed then
409 # you get an anon-enum
411 if ( ref $type_name eq 'ARRAY' && !@values ) {
412 @values = @$type_name;
415 ( scalar @values >= 2 )
416 || __PACKAGE__->_throw_error(
417 "You must have at least two values to enumerate through");
418 my %valid = map { $_ => 1 } @values;
420 register_type_constraint(
421 create_enum_type_constraint(
428 sub create_enum_type_constraint {
429 my ( $type_name, $values ) = @_;
431 Moose::Meta::TypeConstraint::Enum->new(
432 name => $type_name || '__ANON__',
437 sub create_duck_type_constraint {
438 my ( $type_name, $methods ) = @_;
440 Moose::Meta::TypeConstraint::DuckType->new(
441 name => $type_name || '__ANON__',
447 my ($to_match, @cases) = @_;
449 if (@cases % 2 != 0) {
450 $default = pop @cases;
451 (ref $default eq 'CODE')
452 || __PACKAGE__->_throw_error("Default case must be a CODE ref, not $default");
455 my ($type, $action) = splice @cases, 0, 2;
457 unless (blessed $type && $type->isa('Moose::Meta::TypeConstraint')) {
458 $type = find_or_parse_type_constraint($type)
459 || __PACKAGE__->_throw_error("Cannot find or parse the type '$type'")
462 (ref $action eq 'CODE')
463 || __PACKAGE__->_throw_error("Match action must be a CODE ref, not $action");
465 if ($type->check($to_match)) {
466 local $_ = $to_match;
467 return $action->($to_match);
471 || __PACKAGE__->_throw_error("No cases matched for $to_match");
473 local $_ = $to_match;
474 return $default->($to_match);
479 ## --------------------------------------------------------
480 ## desugaring functions ...
481 ## --------------------------------------------------------
483 sub _create_type_constraint ($$$;$$) {
488 my $optimized = shift;
490 my $pkg_defined_in = scalar( caller(1) );
492 if ( defined $name ) {
493 my $type = $REGISTRY->get_type_constraint($name);
495 ( $type->_package_defined_in eq $pkg_defined_in )
497 "The type constraint '$name' has already been created in "
498 . $type->_package_defined_in
499 . " and cannot be created again in "
503 $name =~ /^[\w:\.]+$/
504 or die qq{$name contains invalid characters for a type name.}
505 . qq{ Names can contain alphanumeric character, ":", and "."\n};
510 package_defined_in => $pkg_defined_in,
512 ( $check ? ( constraint => $check ) : () ),
513 ( $message ? ( message => $message ) : () ),
514 ( $optimized ? ( optimized => $optimized ) : () ),
523 : find_or_create_isa_type_constraint($parent)
525 $constraint = $parent->create_child_type(%opts);
528 $constraint = Moose::Meta::TypeConstraint->new(%opts);
531 $REGISTRY->add_type_constraint($constraint)
537 sub _install_type_coercions ($$) {
538 my ( $type_name, $coercion_map ) = @_;
539 my $type = find_type_constraint($type_name);
541 || __PACKAGE__->_throw_error(
542 "Cannot find type '$type_name', perhaps you forgot to load it");
543 if ( $type->has_coercion ) {
544 $type->coercion->add_type_coercions(@$coercion_map);
547 my $type_coercion = Moose::Meta::TypeCoercion->new(
548 type_coercion_map => $coercion_map,
549 type_constraint => $type
551 $type->coercion($type_coercion);
555 ## --------------------------------------------------------
556 ## type notation parsing ...
557 ## --------------------------------------------------------
561 # All I have to say is mugwump++ cause I know
562 # do not even have enough regexp-fu to be able
563 # to have written this (I can only barely
564 # understand it as it is)
569 my $valid_chars = qr{[\w:\.]};
570 my $type_atom = qr{ $valid_chars+ };
574 my $type = qr{ $valid_chars+ (?: \[ \s* (??{$any}) \s* \] )? }x;
575 my $type_capture_parts
576 = qr{ ($valid_chars+) (?: \[ \s* ((??{$any})) \s* \] )? }x;
577 my $type_with_parameter
578 = qr{ $valid_chars+ \[ \s* (??{$any}) \s* \] }x;
580 my $op_union = qr{ \s* \| \s* }x;
581 my $union = qr{ $type (?: $op_union $type )+ }x;
583 $any = qr{ $type | $union }x;
585 sub _parse_parameterized_type_constraint {
586 { no warnings 'void'; $any; } # force capture of interpolated lexical
587 $_[0] =~ m{ $type_capture_parts }x;
591 sub _detect_parameterized_type_constraint {
592 { no warnings 'void'; $any; } # force capture of interpolated lexical
593 $_[0] =~ m{ ^ $type_with_parameter $ }x;
596 sub _parse_type_constraint_union {
597 { no warnings 'void'; $any; } # force capture of interpolated lexical
600 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
603 ( pos($given) eq length($given) )
604 || __PACKAGE__->_throw_error( "'$given' didn't parse (parse-pos="
612 sub _detect_type_constraint_union {
613 { no warnings 'void'; $any; } # force capture of interpolated lexical
614 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
618 ## --------------------------------------------------------
619 # define some basic built-in types
620 ## --------------------------------------------------------
622 # By making these classes immutable before creating all the types we
623 # below, we avoid repeatedly calling the slow MOP-based accessors.
625 inline_constructor => 1,
626 constructor_name => "_new",
628 # these are Class::MOP accessors, so they need inlining
629 inline_accessors => 1
630 ) for grep { $_->is_mutable }
631 map { Class::MOP::class_of($_) }
633 Moose::Meta::TypeConstraint
634 Moose::Meta::TypeConstraint::Union
635 Moose::Meta::TypeConstraint::Parameterized
636 Moose::Meta::TypeConstraint::Parameterizable
637 Moose::Meta::TypeConstraint::Class
638 Moose::Meta::TypeConstraint::Role
639 Moose::Meta::TypeConstraint::Enum
640 Moose::Meta::TypeConstraint::DuckType
641 Moose::Meta::TypeConstraint::Registry
644 type 'Any' => where {1}; # meta-type including all
645 subtype 'Item' => as 'Any'; # base-type
647 subtype 'Undef' => as 'Item' => where { !defined($_) };
648 subtype 'Defined' => as 'Item' => where { defined($_) };
650 subtype 'Bool' => as 'Item' =>
651 where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
653 subtype 'Value' => as 'Defined' => where { !ref($_) } =>
654 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
656 subtype 'Ref' => as 'Defined' => where { ref($_) } =>
657 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
659 subtype 'Str' => as 'Value' => where {1} =>
660 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
662 subtype 'Num' => as 'Str' =>
663 where { Scalar::Util::looks_like_number($_) } =>
664 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
666 subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } =>
667 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
669 subtype 'ScalarRef' => as 'Ref' => where { ref($_) eq 'SCALAR' } =>
671 \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef;
672 subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
673 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
674 subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } =>
676 \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
677 subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
678 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
681 # scalar filehandles are GLOB refs,
682 # but a GLOB ref is not always a filehandle
683 subtype 'FileHandle' => as 'GlobRef' => where {
684 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
686 \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
689 # blessed(qr/.../) returns true,.. how odd
690 subtype 'Object' => as 'Ref' =>
691 where { blessed($_) && blessed($_) ne 'Regexp' } =>
692 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
694 # This type is deprecated.
695 subtype 'Role' => as 'Object' => where { $_->can('does') } =>
696 optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
698 my $_class_name_checker = sub { };
700 subtype 'ClassName' => as 'Str' =>
701 where { Class::MOP::is_class_loaded($_) } => optimize_as
702 \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
704 subtype 'RoleName' => as 'ClassName' => where {
705 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
707 \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
709 ## --------------------------------------------------------
710 # parameterizable types ...
712 $REGISTRY->add_type_constraint(
713 Moose::Meta::TypeConstraint::Parameterizable->new(
715 package_defined_in => __PACKAGE__,
716 parent => find_type_constraint('Ref'),
717 constraint => sub { ref($_) eq 'ARRAY' },
719 \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
720 constraint_generator => sub {
721 my $type_parameter = shift;
722 my $check = $type_parameter->_compiled_type_constraint;
724 foreach my $x (@$_) {
725 ( $check->($x) ) || return;
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 'HASH' },
740 \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
741 constraint_generator => sub {
742 my $type_parameter = shift;
743 my $check = $type_parameter->_compiled_type_constraint;
745 foreach my $x ( values %$_ ) {
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('Item'),
759 constraint => sub {1},
760 constraint_generator => sub {
761 my $type_parameter = shift;
762 my $check = $type_parameter->_compiled_type_constraint;
764 return 1 if not( defined($_) ) || $check->($_);
771 my @PARAMETERIZABLE_TYPES
772 = map { $REGISTRY->get_type_constraint($_) } qw[ArrayRef HashRef Maybe];
774 sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
776 sub add_parameterizable_type {
779 && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
780 || __PACKAGE__->_throw_error(
781 "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
783 push @PARAMETERIZABLE_TYPES => $type;
786 ## --------------------------------------------------------
787 # end of built-in types ...
788 ## --------------------------------------------------------
791 my @BUILTINS = list_all_type_constraints();
792 sub list_all_builtin_type_constraints {@BUILTINS}
799 goto &Moose::throw_error;
810 Moose::Util::TypeConstraints - Type constraint system for Moose
814 use Moose::Util::TypeConstraints;
820 subtype 'NaturalLessThanTen'
823 => message { "This number ($_) is not less than ten!" };
829 enum 'RGBColors' => qw(red green blue);
831 no Moose::Util::TypeConstraints;
835 This module provides Moose with the ability to create custom type
836 constraints to be used in attribute definition.
838 =head2 Important Caveat
840 This is B<NOT> a type system for Perl 5. These are type constraints,
841 and they are not used by Moose unless you tell it to. No type
842 inference is performed, expressions are not typed, etc. etc. etc.
844 A type constraint is at heart a small "check if a value is valid"
845 function. A constraint can be associated with an attribute. This
846 simplifies parameter validation, and makes your code clearer to read,
847 because you can refer to constraints by name.
849 =head2 Slightly Less Important Caveat
851 It is B<always> a good idea to quote your type names.
853 This prevents Perl from trying to execute the call as an indirect
854 object call. This can be an issue when you have a subtype with the
855 same name as a valid class.
859 subtype DateTime => as Object => where { $_->isa('DateTime') };
861 will I<just work>, while this:
864 subtype DateTime => as Object => where { $_->isa('DateTime') };
866 will fail silently and cause many headaches. The simple way to solve
867 this, as well as future proof your subtypes from classes which have
868 yet to have been created, is to quote the type name:
871 subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
873 =head2 Default Type Constraints
875 This module also provides a simple hierarchy for Perl 5 types, here is
876 that hierarchy represented visually.
900 B<NOTE:> Any type followed by a type parameter C<[`a]> can be
901 parameterized, this means you can say:
903 ArrayRef[Int] # an array of integers
904 HashRef[CodeRef] # a hash of str to CODE ref mappings
905 Maybe[Str] # value may be a string, may be undefined
907 If Moose finds a name in brackets that it does not recognize as an
908 existing type, it assumes that this is a class name, for example
909 C<ArrayRef[DateTime]>.
911 B<NOTE:> Unless you parameterize a type, then it is invalid to include
912 the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
913 name, I<not> as a parameterization of C<ArrayRef>.
915 B<NOTE:> The C<Undef> type constraint for the most part works
916 correctly now, but edge cases may still exist, please use it
919 B<NOTE:> The C<ClassName> type constraint does a complex package
920 existence check. This means that your class B<must> be loaded for this
921 type constraint to pass.
923 B<NOTE:> The C<RoleName> constraint checks a string is a I<package
924 name> which is a role, like C<'MyApp::Role::Comparable'>.
926 =head2 Type Constraint Naming
928 Type name declared via this module can only contain alphanumeric
929 characters, colons (:), and periods (.).
931 Since the types created by this module are global, it is suggested
932 that you namespace your types just as you would namespace your
933 modules. So instead of creating a I<Color> type for your
934 B<My::Graphics> module, you would call the type
935 I<My::Graphics::Types::Color> instead.
937 =head2 Use with Other Constraint Modules
939 This module can play nicely with other constraint modules with some
940 slight tweaking. The C<where> clause in types is expected to be a
941 C<CODE> reference which checks it's first argument and returns a
942 boolean. Since most constraint modules work in a similar way, it
943 should be simple to adapt them to work with Moose.
945 For instance, this is how you could use it with
946 L<Declare::Constraints::Simple> to declare a completely new type.
948 type 'HashOfArrayOfObjects',
952 -values => IsArrayRef(IsObject)
956 For more examples see the F<t/200_examples/004_example_w_DCS.t> test
959 Here is an example of using L<Test::Deep> and it's non-test
960 related C<eq_deeply> function.
962 type 'ArrayOfHashOfBarsAndRandomNumbers'
965 array_each(subhashof({
967 random_number => ignore()
971 For a complete example see the
972 F<t/200_examples/005_example_w_TestDeep.t> test file.
976 =head2 Type Constraint Constructors
978 The following functions are used to create type constraints. They
979 will also register the type constraints your create in a global
980 registry that is used to look types up by name.
982 See the L<SYNOPSIS> for an example of how to use these.
986 =item B<< subtype 'Name' => as 'Parent' => where { } ... >>
988 This creates a named subtype.
990 If you provide a parent that Moose does not recognize, it will
991 automatically create a new class type constraint for this name.
993 When creating a named type, the C<subtype> function should either be
994 called with the sugar helpers (C<where>, C<message>, etc), or with a
995 name and a hashref of parameters:
997 subtype( 'Foo', { where => ..., message => ... } );
999 The valid hashref keys are C<as> (the parent), C<where>, C<message>,
1002 =item B<< subtype as 'Parent' => where { } ... >>
1004 This creates an unnamed subtype and will return the type
1005 constraint meta-object, which will be an instance of
1006 L<Moose::Meta::TypeConstraint>.
1008 When creating an anonymous type, the C<subtype> function should either
1009 be called with the sugar helpers (C<where>, C<message>, etc), or with
1010 just a hashref of parameters:
1012 subtype( { where => ..., message => ... } );
1014 =item B<class_type ($class, ?$options)>
1016 Creates a new subtype of C<Object> with the name C<$class> and the
1017 metaclass L<Moose::Meta::TypeConstraint::Class>.
1019 =item B<role_type ($role, ?$options)>
1021 Creates a C<Role> type constraint with the name C<$role> and the
1022 metaclass L<Moose::Meta::TypeConstraint::Role>.
1024 =item B<maybe_type ($type)>
1026 Creates a type constraint for either C<undef> or something of the
1029 =item B<duck_type ($name, @methods)>
1031 This will create a subtype of Object and test to make sure the value
1032 C<can()> do the methods in C<@methods>.
1034 This is intended as an easy way to accept non-Moose objects that
1035 provide a certain interface. If you're using Moose classes, we
1036 recommend that you use a C<requires>-only Role instead.
1038 =item B<duck_type (\@methods)>
1040 If passed an ARRAY reference instead of the C<$name>, C<@methods>
1041 pair, this will create an unnamed duck type. This can be used in an
1042 attribute definition like so:
1046 isa => duck_type( [qw( get_set )] ),
1049 =item B<enum ($name, @values)>
1051 This will create a basic subtype for a given set of strings.
1052 The resulting constraint will be a subtype of C<Str> and
1053 will match any of the items in C<@values>. It is case sensitive.
1054 See the L<SYNOPSIS> for a simple example.
1056 B<NOTE:> This is not a true proper enum type, it is simply
1057 a convenient constraint builder.
1059 =item B<enum (\@values)>
1061 If passed an ARRAY reference instead of the C<$name>, C<@values> pair,
1062 this will create an unnamed enum. This can then be used in an attribute
1065 has 'sort_order' => (
1067 isa => enum([qw[ ascending descending ]]),
1070 =item B<as 'Parent'>
1072 This is just sugar for the type constraint construction syntax.
1074 It takes a single argument, which is the name of a parent type.
1076 =item B<where { ... }>
1078 This is just sugar for the type constraint construction syntax.
1080 It takes a subroutine reference as an argument. When the type
1081 constraint is tested, the reference is run with the value to be tested
1082 in C<$_>. This reference should return true or false to indicate
1083 whether or not the constraint check passed.
1085 =item B<message { ... }>
1087 This is just sugar for the type constraint construction syntax.
1089 It takes a subroutine reference as an argument. When the type
1090 constraint fails, then the code block is run with the value provided
1091 in C<$_>. This reference should return a string, which will be used in
1092 the text of the exception thrown.
1094 =item B<optimize_as { ... }>
1096 This can be used to define a "hand optimized" version of your
1097 type constraint which can be used to avoid traversing a subtype
1098 constraint hierarchy.
1100 B<NOTE:> You should only use this if you know what you are doing,
1101 all the built in types use this, so your subtypes (assuming they
1102 are shallow) will not likely need to use this.
1104 =item B<< type 'Name' => where { } ... >>
1106 This creates a base type, which has no parent.
1108 The C<type> function should either be called with the sugar helpers
1109 (C<where>, C<message>, etc), or with a name and a hashref of
1112 type( 'Foo', { where => ..., message => ... } );
1114 The valid hashref keys are C<where>, C<message>, and C<optimize_as>.
1118 =head2 Type Constraint Utilities
1122 =item B<< match_on_type $value => ( $type => \&action, ... ?\&default ) >>
1124 This is a utility function for doing simple type based dispatching
1125 similar to match/case in O'Caml and case/of in Haskell. It does not
1126 claim to be as featureful as either of those and does not support any
1127 kind of automatic destructuring bind. However it is suitable for a fair
1128 amount of your dispatching needs, for instance, here is a simple
1129 Perl pretty printer dispatching over the core Moose types.
1136 '{ ' . (join ", " => map {
1137 $_ . ' => ' . ppprint( $hash->{ $_ } )
1138 } sort keys %$hash ) . ' }' },
1141 '[ '.(join ", " => map { ppprint( $_ ) } @$array ).' ]' },
1142 CodeRef => sub { 'sub { ... }' },
1143 RegexpRef => sub { 'qr/' . $_ . '/' },
1144 GlobRef => sub { '*' . B::svref_2object($_)->NAME },
1145 Object => sub { $_->can('to_string') ? $_->to_string : $_ },
1146 ScalarRef => sub { '\\' . ppprint( ${$_} ) },
1148 Str => sub { '"'. $_ . '"' },
1149 Undef => sub { 'undef' },
1150 => sub { die "I don't know what $_ is" };
1153 Or a simple JSON serializer:
1160 '{ ' . (join ", " => map {
1161 '"' . $_ . '" : ' . to_json( $hash->{ $_ } )
1162 } sort keys %$hash ) . ' }' },
1165 '[ ' . (join ", " => map { to_json( $_ ) } @$array ) . ' ]' },
1167 Str => sub { '"'. $_ . '"' },
1168 Undef => sub { 'null' },
1169 => sub { die "$_ is not acceptable json type" };
1172 Based on a mapping of C<$type> to C<\&action>, where C<$type> can be
1173 either a string type or a L<Moose::Meta::TypeConstraint> object, and
1174 C<\&action> is a CODE ref, this function will dispatch on the first
1175 match for C<$value>. It is possible to have a catch-all at the end
1176 in the form of a C<\&default> CODE ref.
1180 =head2 Type Coercion Constructors
1182 You can define coercions for type constraints, which allow you to
1183 automatically transform values to something valid for the type
1184 constraint. If you ask your accessor to coerce, then Moose will run
1185 the type-coercion code first, followed by the type constraint
1186 check. This feature should be used carefully as it is very powerful
1187 and could easily take off a limb if you are not careful.
1189 See the L<SYNOPSIS> for an example of how to use these.
1193 =item B<< coerce 'Name' => from 'OtherName' => via { ... } >>
1195 This defines a coercion from one type to another. The C<Name> argument
1196 is the type you are coercing I<to>.
1198 =item B<from 'OtherName'>
1200 This is just sugar for the type coercion construction syntax.
1202 It takes a single type name (or type object), which is the type being
1205 =item B<via { ... }>
1207 This is just sugar for the type coercion construction syntax.
1209 It takes a subroutine reference. This reference will be called with
1210 the value to be coerced in C<$_>. It is expected to return a new value
1211 of the proper type for the coercion.
1215 =head2 Creating and Finding Type Constraints
1217 These are additional functions for creating and finding type
1218 constraints. Most of these functions are not available for
1219 importing. The ones that are importable as specified.
1223 =item B<find_type_constraint($type_name)>
1225 This function can be used to locate the L<Moose::Meta::TypeConstraint>
1226 object for a named type.
1228 This function is importable.
1230 =item B<register_type_constraint($type_object)>
1232 This function will register a L<Moose::Meta::TypeConstraint> with the
1233 global type registry.
1235 This function is importable.
1237 =item B<normalize_type_constraint_name($type_constraint_name)>
1239 This method takes a type constraint name and returns the normalized
1240 form. This removes any whitespace in the string.
1242 =item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
1244 This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1245 or a list of names. It returns a new
1246 L<Moose::Meta::TypeConstraint::Union> object.
1248 =item B<create_parameterized_type_constraint($type_name)>
1250 Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1251 this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1252 object. The C<BaseType> must exist already exist as a parameterizable
1255 =item B<create_class_type_constraint($class, $options)>
1257 Given a class name this function will create a new
1258 L<Moose::Meta::TypeConstraint::Class> object for that class name.
1260 The C<$options> is a hash reference that will be passed to the
1261 L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
1263 =item B<create_role_type_constraint($role, $options)>
1265 Given a role name this function will create a new
1266 L<Moose::Meta::TypeConstraint::Role> object for that role name.
1268 The C<$options> is a hash reference that will be passed to the
1269 L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
1271 =item B<create_enum_type_constraint($name, $values)>
1273 Given a enum name this function will create a new
1274 L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1276 =item B<create_duck_type_constraint($name, $methods)>
1278 Given a duck type name this function will create a new
1279 L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
1281 =item B<find_or_parse_type_constraint($type_name)>
1283 Given a type name, this first attempts to find a matching constraint
1284 in the global registry.
1286 If the type name is a union or parameterized type, it will create a
1287 new object of the appropriate, but if given a "regular" type that does
1288 not yet exist, it simply returns false.
1290 When given a union or parameterized type, the member or base type must
1293 If it creates a new union or parameterized type, it will add it to the
1296 =item B<find_or_create_isa_type_constraint($type_name)>
1298 =item B<find_or_create_does_type_constraint($type_name)>
1300 These functions will first call C<find_or_parse_type_constraint>. If
1301 that function does not return a type, a new anonymous type object will
1304 The C<isa> variant will use C<create_class_type_constraint> and the
1305 C<does> variant will use C<create_role_type_constraint>.
1307 =item B<get_type_constraint_registry>
1309 Returns the L<Moose::Meta::TypeConstraint::Registry> object which
1310 keeps track of all type constraints.
1312 =item B<list_all_type_constraints>
1314 This will return a list of type constraint names in the global
1315 registry. You can then fetch the actual type object using
1316 C<find_type_constraint($type_name)>.
1318 =item B<list_all_builtin_type_constraints>
1320 This will return a list of builtin type constraints, meaning those
1321 which are defined in this module. See the L<Default Type Constraints>
1322 section for a complete list.
1324 =item B<export_type_constraints_as_functions>
1326 This will export all the current type constraints as functions into
1327 the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1328 mostly used for testing, but it might prove useful to others.
1330 =item B<get_all_parameterizable_types>
1332 This returns all the parameterizable types that have been registered,
1333 as a list of type objects.
1335 =item B<add_parameterizable_type($type)>
1337 Adds C<$type> to the list of parameterizable types
1343 All complex software has bugs lurking in it, and this module is no
1344 exception. If you find a bug please either email me, or add the bug
1349 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1351 =head1 COPYRIGHT AND LICENSE
1353 Copyright 2006-2009 by Infinity Interactive, Inc.
1355 L<http://www.iinteractive.com>
1357 This library is free software; you can redistribute it and/or modify
1358 it under the same terms as Perl itself.