2 package Moose::Util::TypeConstraints;
8 use Sub::Name 'subname';
9 use Scalar::Util 'blessed';
11 our $VERSION = '0.02';
13 use Moose::Meta::TypeConstraint;
14 use Moose::Meta::TypeCoercion;
18 my $pkg = shift || caller();
19 return if $pkg eq ':no_export';
21 foreach my $export (qw(type subtype as where coerce from via)) {
22 *{"${pkg}::${export}"} = \&{"${export}"};
28 sub find_type_constraint { $TYPES{$_[0]} }
30 sub create_type_constraint {
31 my ($name, $parent, $constraint) = @_;
32 (not exists $TYPES{$name})
33 || confess "The type constraint '$name' has already been created";
34 $parent = find_type_constraint($parent) if defined $parent;
35 $TYPES{$name} = Moose::Meta::TypeConstraint->new(
38 constraint => $constraint,
42 sub find_type_coercion {
43 my $type_name = shift;
44 $TYPES{$type_name}->coercion_code;
47 sub register_type_coercion {
48 my ($type_name, $type_coercion) = @_;
49 my $type = $TYPES{$type_name};
50 (!$type->has_coercion)
51 || confess "The type coercion for '$type_name' has already been registered";
52 $type->set_coercion_code($type_coercion);
55 sub export_type_contstraints_as_functions {
58 foreach my $constraint (keys %TYPES) {
59 *{"${pkg}::${constraint}"} = $TYPES{$constraint}->constraint_code;
66 my ($name, $check) = @_;
67 create_type_constraint($name, undef, $check);
72 my ($name, $parent, $check) = @_;
73 create_type_constraint($name, $parent, $check);
76 my ($parent, $check) = @_;
77 $parent = find_type_constraint($parent);
78 return Moose::Meta::TypeConstraint->new(
87 my ($type_name, @coercion_map) = @_;
89 while (@coercion_map) {
90 my ($constraint_name, $action) = splice(@coercion_map, 0, 2);
91 my $constraint = find_type_constraint($constraint_name)->constraint_code;
93 || confess "Could not find the type constraint ($constraint_name)";
94 push @coercions => [ $constraint, $action ];
96 register_type_coercion($type_name, sub {
98 foreach my $coercion (@coercions) {
99 my ($constraint, $converter) = @$coercion;
100 if (defined $constraint->($thing)) {
102 return $converter->($thing);
110 sub from ($) { $_[0] }
111 sub where (&) { $_[0] }
112 sub via (&) { $_[0] }
114 # define some basic types
116 type Any => where { 1 };
118 type Value => where { !ref($_) };
119 type Ref => where { ref($_) };
121 subtype Int => as Value => where { Scalar::Util::looks_like_number($_) };
122 subtype Str => as Value => where { !Scalar::Util::looks_like_number($_) };
124 subtype ScalarRef => as Ref => where { ref($_) eq 'SCALAR' };
125 subtype ArrayRef => as Ref => where { ref($_) eq 'ARRAY' };
126 subtype HashRef => as Ref => where { ref($_) eq 'HASH' };
127 subtype CodeRef => as Ref => where { ref($_) eq 'CODE' };
128 subtype RegexpRef => as Ref => where { ref($_) eq 'Regexp' };
131 # blessed(qr/.../) returns true,.. how odd
132 subtype Object => as Ref => where { blessed($_) && blessed($_) ne 'Regexp' };
142 Moose::Util::TypeConstraints - Type constraint system for Moose
146 use Moose::Util::TypeConstraints;
148 type Num => where { Scalar::Util::looks_like_number($_) };
154 subtype NaturalLessThanTen
156 => where { $_ < 10 };
164 This module provides Moose with the ability to create type contraints
165 to be are used in both attribute definitions and for method argument
168 This is B<NOT> a type system for Perl 5.
170 This module also provides a simple hierarchy for Perl 5 types, this
171 could probably use some work, but it works for me at the moment.
185 Suggestions for improvement are welcome.
189 =head2 Type Constraint Registry
193 =item B<find_type_constraint ($type_name)>
195 =item B<create_type_constraint ($type_name, $type_constraint)>
197 =item B<find_type_coercion>
199 =item B<register_type_coercion>
201 =item B<export_type_contstraints_as_functions>
203 =item B<dump_type_constraints>
207 =head2 Type Constraint Constructors
227 =head2 Built-in Type Constraints
257 All complex software has bugs lurking in it, and this module is no
258 exception. If you find a bug please either email me, or add the bug
263 Stevan Little E<lt>stevan@iinteractive.comE<gt>
265 =head1 COPYRIGHT AND LICENSE
267 Copyright 2006 by Infinity Interactive, Inc.
269 L<http://www.iinteractive.com>
271 This library is free software; you can redistribute it and/or modify
272 it under the same terms as Perl itself.