getting-there
[gitmo/Moose.git] / lib / Moose / Meta / TypeConstraint.pm
CommitLineData
4e036ee4 1
2package Moose::Meta::TypeConstraint;
3
4use strict;
5use warnings;
6use metaclass;
7
66811d63 8use Sub::Name 'subname';
9use Carp 'confess';
10
76d37e5a 11our $VERSION = '0.02';
66811d63 12
66811d63 13__PACKAGE__->meta->add_attribute('name' => (reader => 'name' ));
14__PACKAGE__->meta->add_attribute('parent' => (reader => 'parent' ));
15__PACKAGE__->meta->add_attribute('constraint' => (reader => 'constraint'));
76d37e5a 16__PACKAGE__->meta->add_attribute('message' => (
17 accessor => 'message',
18 predicate => 'has_message'
19));
a27aa600 20__PACKAGE__->meta->add_attribute('coercion' => (
21 accessor => 'coercion',
22 predicate => 'has_coercion'
23));
66811d63 24
25# private accessor
26__PACKAGE__->meta->add_attribute('compiled_type_constraint' => (
27 accessor => '_compiled_type_constraint'
28));
29
66811d63 30sub new {
a27aa600 31 my $class = shift;
32 my $self = $class->meta->new_object(@_);
66811d63 33 $self->compile_type_constraint();
34 return $self;
35}
36
37sub compile_type_constraint () {
a27aa600 38 my $self = shift;
39 my $check = $self->constraint;
66811d63 40 (defined $check)
41 || confess "Could not compile type constraint '" . $self->name . "' because no constraint check";
42 my $parent = $self->parent;
43 if (defined $parent) {
a27aa600 44 # we have a subtype ...
66811d63 45 $parent = $parent->_compiled_type_constraint;
46 $self->_compiled_type_constraint(subname $self->name => sub {
47 local $_ = $_[0];
48 return undef unless defined $parent->($_[0]) && $check->($_[0]);
49 $_[0];
50 });
51 }
52 else {
a27aa600 53 # we have a type ....
66811d63 54 $self->_compiled_type_constraint(subname $self->name => sub {
55 local $_ = $_[0];
56 return undef unless $check->($_[0]);
57 $_[0];
58 });
59 }
60}
61
a27aa600 62sub check { $_[0]->_compiled_type_constraint->($_[1]) }
4e036ee4 63
76d37e5a 64sub validate {
65 my ($self, $value) = @_;
66 if ($self->_compiled_type_constraint->($value)) {
67 return undef;
68 }
69 else {
70 if ($self->has_message) {
71 local $_ = $value;
72 return $self->message->($value);
73 }
74 else {
75 return "Validation failed for '" . $self->name . "' failed.";
76 }
77 }
78}
79
4e036ee4 801;
81
82__END__
83
84=pod
85
86=head1 NAME
87
6ba6d68c 88Moose::Meta::TypeConstraint - The Moose Type Constraint metaclass
4e036ee4 89
90=head1 DESCRIPTION
91
6ba6d68c 92For the most part, the only time you will ever encounter an
93instance of this class is if you are doing some serious deep
94introspection. This API should not be considered final, but
95it is B<highly unlikely> that this will matter to a regular
96Moose user.
97
98If you wish to use features at this depth, please come to the
99#moose IRC channel on irc.perl.org and we can talk :)
100
4e036ee4 101=head1 METHODS
102
103=over 4
104
105=item B<meta>
106
107=item B<new>
108
6ba6d68c 109=item B<compile_type_constraint>
110
76d37e5a 111=item B<check ($value)>
112
113This method will return a true (C<1>) if the C<$value> passes the
114constraint, and false (C<0>) otherwise.
115
116=item B<validate ($value)>
117
118This method is similar to C<check>, but it deals with the error
119message. If the C<$value> passes the constraint, C<undef> will be
120returned. If the C<$value> does B<not> pass the constraint, then
121the C<message> will be used to construct a custom error message.
6ba6d68c 122
4e036ee4 123=item B<name>
124
66811d63 125=item B<parent>
126
66811d63 127=item B<constraint>
128
76d37e5a 129=item B<has_message>
130
131=item B<message>
132
4e036ee4 133=item B<has_coercion>
134
a27aa600 135=item B<coercion>
136
4e036ee4 137=back
138
139=head1 BUGS
140
141All complex software has bugs lurking in it, and this module is no
142exception. If you find a bug please either email me, or add the bug
143to cpan-RT.
144
145=head1 AUTHOR
146
147Stevan Little E<lt>stevan@iinteractive.comE<gt>
148
149=head1 COPYRIGHT AND LICENSE
150
151Copyright 2006 by Infinity Interactive, Inc.
152
153L<http://www.iinteractive.com>
154
155This library is free software; you can redistribute it and/or modify
156it under the same terms as Perl itself.
157
158=cut