0.01
[gitmo/Moose.git] / lib / Moose / Util / TypeConstraints.pm
CommitLineData
a15dff8d 1
2package Moose::Util::TypeConstraints;
3
4use strict;
5use warnings;
6
7use Sub::Name 'subname';
8use Scalar::Util 'blessed';
9
10our $VERSION = '0.01';
11
12sub import {
13 shift;
14 my $pkg = shift || caller();
15 return if $pkg eq ':no_export';
16 no strict 'refs';
17 foreach my $export (qw(
18 type subtype as where
19 )) {
20 *{"${pkg}::${export}"} = \&{"${export}"};
21 }
22
23 foreach my $constraint (qw(
24 Any
25 Value Ref
26 Str Int
27 ScalarRef ArrayRef HashRef CodeRef RegexpRef
28 Object
29 )) {
30 *{"${pkg}::${constraint}"} = \&{"${constraint}"};
31 }
32
33}
34
35my %TYPES;
36
37# might need this later
38#sub find_type_constraint { $TYPES{$_[0]} }
39
40sub type ($$) {
41 my ($name, $check) = @_;
42 my $pkg = caller();
43 my $full_name = "${pkg}::${name}";
44 no strict 'refs';
45 *{$full_name} = $TYPES{$name} = subname $full_name => sub {
46 return $TYPES{$name} unless defined $_[0];
47 local $_ = $_[0];
48 return undef unless $check->($_[0]);
49 $_[0];
50 };
51}
52
53sub subtype ($$;$) {
54 my ($name, $parent, $check) = @_;
55 if (defined $check) {
56 my $pkg = caller();
57 my $full_name = "${pkg}::${name}";
58 no strict 'refs';
59 $parent = $TYPES{$parent} unless $parent && ref($parent) eq 'CODE';
60 *{$full_name} = $TYPES{$name} = subname $full_name => sub {
61 return $TYPES{$name} unless defined $_[0];
62 local $_ = $_[0];
63 return undef unless defined $parent->($_[0]) && $check->($_[0]);
64 $_[0];
65 };
66 }
67 else {
68 ($parent, $check) = ($name, $parent);
69 $parent = $TYPES{$parent} unless $parent && ref($parent) eq 'CODE';
70 return subname((caller() . '::__anon_subtype__') => sub {
71 return $TYPES{$name} unless defined $_[0];
72 local $_ = $_[0];
73 return undef unless defined $parent->($_[0]) && $check->($_[0]);
74 $_[0];
75 });
76 }
77}
78
79sub as ($) { $_[0] }
80sub where (&) { $_[0] }
81
82# define some basic types
83
84type Any => where { 1 };
85
86type Value => where { !ref($_) };
87type Ref => where { ref($_) };
88
89subtype Int => as Value => where { Scalar::Util::looks_like_number($_) };
90subtype Str => as Value => where { !Scalar::Util::looks_like_number($_) };
91
92subtype ScalarRef => as Ref => where { ref($_) eq 'SCALAR' };
93subtype ArrayRef => as Ref => where { ref($_) eq 'ARRAY' };
94subtype HashRef => as Ref => where { ref($_) eq 'HASH' };
95subtype CodeRef => as Ref => where { ref($_) eq 'CODE' };
96subtype RegexpRef => as Ref => where { ref($_) eq 'Regexp' };
97
98# NOTE:
99# blessed(qr/.../) returns true,.. how odd
100subtype Object => as Ref => where { blessed($_) && blessed($_) ne 'Regexp' };
101
1021;
103
104__END__
105
106=pod
107
108=head1 NAME
109
e522431d 110Moose::Util::TypeConstraints - Type constraint system for Moose
a15dff8d 111
112=head1 SYNOPSIS
113
114 use Moose::Util::TypeConstraints;
115
116 type Num => where { Scalar::Util::looks_like_number($_) };
117
118 subtype Natural
119 => as Num
120 => where { $_ > 0 };
121
122 subtype NaturalLessThanTen
123 => as Natural
124 => where { $_ < 10 };
125
126=head1 DESCRIPTION
127
e522431d 128This module provides Moose with the ability to create type contraints
129to be are used in both attribute definitions and for method argument
130validation.
131
132This is B<NOT> a type system for Perl 5.
133
134The type and subtype constraints are basically functions which will
135validate their first argument. If called with no arguments, they will
136return themselves (this is syntactic sugar for Moose attributes).
137
138This module also provides a simple hierarchy for Perl 5 types, this
139could probably use some work, but it works for me at the moment.
140
141 Any
142 Value
143 Int
144 Str
145 Ref
146 ScalarRef
147 ArrayRef
148 HashRef
149 CodeRef
150 RegexpRef
151 Object
152
153Suggestions for improvement are welcome.
154
a15dff8d 155=head1 FUNCTIONS
156
157=head2 Type Constraint Constructors
158
159=over 4
160
161=item B<type>
162
163=item B<subtype>
164
165=item B<as>
166
167=item B<where>
168
169=back
170
171=head2 Built-in Type Constraints
172
173=over 4
174
175=item B<Any>
176
177=item B<Value>
178
179=item B<Int>
180
181=item B<Str>
182
183=item B<Ref>
184
185=item B<ArrayRef>
186
187=item B<CodeRef>
188
189=item B<HashRef>
190
191=item B<RegexpRef>
192
193=item B<ScalarRef>
194
195=item B<Object>
196
197=back
198
199=head1 BUGS
200
201All complex software has bugs lurking in it, and this module is no
202exception. If you find a bug please either email me, or add the bug
203to cpan-RT.
204
a15dff8d 205=head1 AUTHOR
206
207Stevan Little E<lt>stevan@iinteractive.comE<gt>
208
209=head1 COPYRIGHT AND LICENSE
210
211Copyright 2006 by Infinity Interactive, Inc.
212
213L<http://www.iinteractive.com>
214
215This library is free software; you can redistribute it and/or modify
216it under the same terms as Perl itself.
217
218=cut