more-tweaks
[gitmo/Moose.git] / lib / Moose / Util / TypeConstraints.pm
CommitLineData
a15dff8d 1
2package Moose::Util::TypeConstraints;
3
4use strict;
5use warnings;
6
e90c03d0 7use Carp 'confess';
a15dff8d 8use Scalar::Util 'blessed';
9
5569c072 10our $VERSION = '0.02';
a15dff8d 11
4e036ee4 12use Moose::Meta::TypeConstraint;
2ca63f5d 13use Moose::Meta::TypeCoercion;
4e036ee4 14
a15dff8d 15sub import {
16 shift;
17 my $pkg = shift || caller();
a15dff8d 18 no strict 'refs';
7c13858b 19 foreach my $export (qw(type subtype as where coerce from via find_type_constraint)) {
a15dff8d 20 *{"${pkg}::${export}"} = \&{"${export}"};
a15dff8d 21 }
a15dff8d 22}
23
182134e8 24{
25 my %TYPES;
82168dbb 26 sub find_type_constraint { $TYPES{$_[0]} }
182134e8 27
7c13858b 28 sub _create_type_constraint {
a27aa600 29 my ($name, $parent, $check) = @_;
30 (!exists $TYPES{$name})
31 || confess "The type constraint '$name' has already been created"
32 if defined $name;
7c13858b 33 $parent = $TYPES{$parent} if defined $parent;
a27aa600 34 my $constraint = Moose::Meta::TypeConstraint->new(
35 name => $name || '__ANON__',
66811d63 36 parent => $parent,
a27aa600 37 constraint => $check,
4e036ee4 38 );
a27aa600 39 $TYPES{$name} = $constraint if defined $name;
40 return $constraint;
182134e8 41 }
182134e8 42
7c13858b 43 sub _install_type_coercions {
a27aa600 44 my ($type_name, $coercion_map) = @_;
7c13858b 45 my $type = $TYPES{$type_name};
4e036ee4 46 (!$type->has_coercion)
d46a48f3 47 || confess "The type coercion for '$type_name' has already been registered";
a27aa600 48 my $type_coercion = Moose::Meta::TypeCoercion->new(
49 type_coercion_map => $coercion_map,
50 type_constraint => $type
51 );
52 $type->coercion($type_coercion);
182134e8 53 }
66811d63 54
55 sub export_type_contstraints_as_functions {
56 my $pkg = caller();
57 no strict 'refs';
58 foreach my $constraint (keys %TYPES) {
a27aa600 59 *{"${pkg}::${constraint}"} = $TYPES{$constraint}->_compiled_type_constraint;
66811d63 60 }
61 }
182134e8 62}
a15dff8d 63
7c13858b 64# type constructors
a15dff8d 65
66sub type ($$) {
67 my ($name, $check) = @_;
7c13858b 68 _create_type_constraint($name, undef, $check);
a15dff8d 69}
70
71sub subtype ($$;$) {
a27aa600 72 unshift @_ => undef if scalar @_ == 2;
7c13858b 73 _create_type_constraint(@_);
a15dff8d 74}
75
4b598ea3 76sub coerce ($@) {
66811d63 77 my ($type_name, @coercion_map) = @_;
7c13858b 78 _install_type_coercions($type_name, \@coercion_map);
182134e8 79}
80
a15dff8d 81sub as ($) { $_[0] }
d6e2d9a1 82sub from ($) { $_[0] }
a15dff8d 83sub where (&) { $_[0] }
d6e2d9a1 84sub via (&) { $_[0] }
a15dff8d 85
86# define some basic types
87
88type Any => where { 1 };
89
90type Value => where { !ref($_) };
91type Ref => where { ref($_) };
92
93subtype Int => as Value => where { Scalar::Util::looks_like_number($_) };
94subtype Str => as Value => where { !Scalar::Util::looks_like_number($_) };
95
96subtype ScalarRef => as Ref => where { ref($_) eq 'SCALAR' };
97subtype ArrayRef => as Ref => where { ref($_) eq 'ARRAY' };
98subtype HashRef => as Ref => where { ref($_) eq 'HASH' };
99subtype CodeRef => as Ref => where { ref($_) eq 'CODE' };
100subtype RegexpRef => as Ref => where { ref($_) eq 'Regexp' };
101
102# NOTE:
103# blessed(qr/.../) returns true,.. how odd
104subtype Object => as Ref => where { blessed($_) && blessed($_) ne 'Regexp' };
105
1061;
107
108__END__
109
110=pod
111
112=head1 NAME
113
e522431d 114Moose::Util::TypeConstraints - Type constraint system for Moose
a15dff8d 115
116=head1 SYNOPSIS
117
118 use Moose::Util::TypeConstraints;
119
120 type Num => where { Scalar::Util::looks_like_number($_) };
121
122 subtype Natural
123 => as Num
124 => where { $_ > 0 };
125
126 subtype NaturalLessThanTen
127 => as Natural
128 => where { $_ < 10 };
6b8bd8d3 129
130 coerce Num
d6e2d9a1 131 => from Str
132 => via { 0+$_ };
a15dff8d 133
134=head1 DESCRIPTION
135
e522431d 136This module provides Moose with the ability to create type contraints
137to be are used in both attribute definitions and for method argument
138validation.
139
140This is B<NOT> a type system for Perl 5.
141
e522431d 142This module also provides a simple hierarchy for Perl 5 types, this
143could probably use some work, but it works for me at the moment.
144
145 Any
146 Value
147 Int
148 Str
149 Ref
150 ScalarRef
151 ArrayRef
152 HashRef
153 CodeRef
154 RegexpRef
155 Object
156
157Suggestions for improvement are welcome.
158
a15dff8d 159=head1 FUNCTIONS
160
182134e8 161=head2 Type Constraint Registry
162
163=over 4
164
165=item B<find_type_constraint ($type_name)>
166
7c13858b 167=item B<_create_type_constraint ($type_name, $type_constraint)>
182134e8 168
7c13858b 169=item B<_install_type_coercions>
182134e8 170
171=item B<export_type_contstraints_as_functions>
172
173=back
174
a15dff8d 175=head2 Type Constraint Constructors
176
177=over 4
178
179=item B<type>
180
181=item B<subtype>
182
183=item B<as>
184
185=item B<where>
186
182134e8 187=item B<coerce>
188
d6e2d9a1 189=item B<from>
190
191=item B<via>
182134e8 192
a15dff8d 193=back
194
195=head2 Built-in Type Constraints
196
197=over 4
198
199=item B<Any>
200
201=item B<Value>
202
203=item B<Int>
204
205=item B<Str>
206
207=item B<Ref>
208
209=item B<ArrayRef>
210
211=item B<CodeRef>
212
213=item B<HashRef>
214
215=item B<RegexpRef>
216
217=item B<ScalarRef>
218
219=item B<Object>
220
221=back
222
223=head1 BUGS
224
225All complex software has bugs lurking in it, and this module is no
226exception. If you find a bug please either email me, or add the bug
227to cpan-RT.
228
a15dff8d 229=head1 AUTHOR
230
231Stevan Little E<lt>stevan@iinteractive.comE<gt>
232
233=head1 COPYRIGHT AND LICENSE
234
235Copyright 2006 by Infinity Interactive, Inc.
236
237L<http://www.iinteractive.com>
238
239This library is free software; you can redistribute it and/or modify
240it under the same terms as Perl itself.
241
242=cut