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, $check) = @_;
32 (!exists $TYPES{$name})
33 || confess "The type constraint '$name' has already been created"
35 $parent = find_type_constraint($parent) if defined $parent;
36 my $constraint = Moose::Meta::TypeConstraint->new(
37 name => $name || '__ANON__',
41 $TYPES{$name} = $constraint if defined $name;
45 sub install_type_coercions {
46 my ($type_name, $coercion_map) = @_;
47 my $type = find_type_constraint($type_name);
48 (!$type->has_coercion)
49 || confess "The type coercion for '$type_name' has already been registered";
50 my $type_coercion = Moose::Meta::TypeCoercion->new(
51 type_coercion_map => $coercion_map,
52 type_constraint => $type
54 $type->coercion($type_coercion);
57 sub export_type_contstraints_as_functions {
60 foreach my $constraint (keys %TYPES) {
61 *{"${pkg}::${constraint}"} = $TYPES{$constraint}->_compiled_type_constraint;
68 my ($name, $check) = @_;
69 create_type_constraint($name, undef, $check);
73 unshift @_ => undef if scalar @_ == 2;
74 create_type_constraint(@_);
78 my ($type_name, @coercion_map) = @_;
79 install_type_coercions($type_name, \@coercion_map);
83 sub from ($) { $_[0] }
84 sub where (&) { $_[0] }
87 # define some basic types
89 type Any => where { 1 };
91 type Value => where { !ref($_) };
92 type Ref => where { ref($_) };
94 subtype Int => as Value => where { Scalar::Util::looks_like_number($_) };
95 subtype Str => as Value => where { !Scalar::Util::looks_like_number($_) };
97 subtype ScalarRef => as Ref => where { ref($_) eq 'SCALAR' };
98 subtype ArrayRef => as Ref => where { ref($_) eq 'ARRAY' };
99 subtype HashRef => as Ref => where { ref($_) eq 'HASH' };
100 subtype CodeRef => as Ref => where { ref($_) eq 'CODE' };
101 subtype RegexpRef => as Ref => where { ref($_) eq 'Regexp' };
104 # blessed(qr/.../) returns true,.. how odd
105 subtype Object => as Ref => where { blessed($_) && blessed($_) ne 'Regexp' };
115 Moose::Util::TypeConstraints - Type constraint system for Moose
119 use Moose::Util::TypeConstraints;
121 type Num => where { Scalar::Util::looks_like_number($_) };
127 subtype NaturalLessThanTen
129 => where { $_ < 10 };
137 This module provides Moose with the ability to create type contraints
138 to be are used in both attribute definitions and for method argument
141 This is B<NOT> a type system for Perl 5.
143 This module also provides a simple hierarchy for Perl 5 types, this
144 could probably use some work, but it works for me at the moment.
158 Suggestions for improvement are welcome.
162 =head2 Type Constraint Registry
166 =item B<find_type_constraint ($type_name)>
168 =item B<create_type_constraint ($type_name, $type_constraint)>
170 =item B<install_type_coercions>
172 =item B<export_type_contstraints_as_functions>
176 =head2 Type Constraint Constructors
196 =head2 Built-in Type Constraints
226 All complex software has bugs lurking in it, and this module is no
227 exception. If you find a bug please either email me, or add the bug
232 Stevan Little E<lt>stevan@iinteractive.comE<gt>
234 =head1 COPYRIGHT AND LICENSE
236 Copyright 2006 by Infinity Interactive, Inc.
238 L<http://www.iinteractive.com>
240 This library is free software; you can redistribute it and/or modify
241 it under the same terms as Perl itself.