make a dev version to go with the CMOP release
[gitmo/Moose.git] / lib / Moose / Meta / TypeCoercion.pm
CommitLineData
6bf30233 1
2package Moose::Meta::TypeCoercion;
3
4use strict;
5use warnings;
6use metaclass;
7
a27aa600 8use Moose::Meta::Attribute;
a3c7e2fe 9use Moose::Util::TypeConstraints ();
a27aa600 10
a532c4ac 11our $VERSION = '0.71_01';
e606ae5f 12$VERSION = eval $VERSION;
d44714be 13our $AUTHORITY = 'cpan:STEVAN';
6bf30233 14
a27aa600 15__PACKAGE__->meta->add_attribute('type_coercion_map' => (
16 reader => 'type_coercion_map',
17 default => sub { [] }
18));
d44714be 19
a27aa600 20__PACKAGE__->meta->add_attribute(
21 Moose::Meta::Attribute->new('type_constraint' => (
22 reader => 'type_constraint',
23 weak_ref => 1
24 ))
25);
26
27# private accessor
28__PACKAGE__->meta->add_attribute('compiled_type_coercion' => (
29 accessor => '_compiled_type_coercion'
30));
31
32sub new {
33 my $class = shift;
34 my $self = $class->meta->new_object(@_);
41e007e4 35 $self->compile_type_coercion;
a27aa600 36 return $self;
37}
38
39sub compile_type_coercion {
40 my $self = shift;
41 my @coercion_map = @{$self->type_coercion_map};
42 my @coercions;
43 while (@coercion_map) {
44 my ($constraint_name, $action) = splice(@coercion_map, 0, 2);
9c637fca 45 my $type_constraint = ref $constraint_name ? $constraint_name : Moose::Util::TypeConstraints::find_or_parse_type_constraint($constraint_name);
70ea9161 46
47 unless ( defined $type_constraint ) {
48 require Moose;
49 Moose->throw_error("Could not find the type constraint ($constraint_name) to coerce from");
50 }
51
e95c7c42 52 push @coercions => [
53 $type_constraint->_compiled_type_constraint,
54 $action
55 ];
a27aa600 56 }
57 $self->_compiled_type_coercion(sub {
58 my $thing = shift;
59 foreach my $coercion (@coercions) {
60 my ($constraint, $converter) = @$coercion;
42bc21a4 61 if ($constraint->($thing)) {
6f9ff1af 62 local $_ = $thing;
a27aa600 63 return $converter->($thing);
64 }
65 }
66 return $thing;
67 });
68}
69
41e007e4 70sub has_coercion_for_type {
71 my ($self, $type_name) = @_;
72 my %coercion_map = @{$self->type_coercion_map};
73 exists $coercion_map{$type_name} ? 1 : 0;
74}
75
76sub add_type_coercions {
77 my ($self, @new_coercion_map) = @_;
78
79 my $coercion_map = $self->type_coercion_map;
80 my %has_coercion = @$coercion_map;
81
82 while (@new_coercion_map) {
83 my ($constraint_name, $action) = splice(@new_coercion_map, 0, 2);
70ea9161 84
85 if ( exists $has_coercion{$constraint_name} ) {
86 require Moose;
87 Moose->throw_error("A coercion action already exists for '$constraint_name'")
88 }
89
41e007e4 90 push @{$coercion_map} => ($constraint_name, $action);
91 }
92
93 # and re-compile ...
94 $self->compile_type_coercion;
95}
96
a27aa600 97sub coerce { $_[0]->_compiled_type_coercion->($_[1]) }
98
99
6bf30233 1001;
101
102__END__
103
104=pod
105
106=head1 NAME
107
6ba6d68c 108Moose::Meta::TypeCoercion - The Moose Type Coercion metaclass
6bf30233 109
110=head1 DESCRIPTION
111
6ba6d68c 112For the most part, the only time you will ever encounter an
113instance of this class is if you are doing some serious deep
114introspection. This API should not be considered final, but
115it is B<highly unlikely> that this will matter to a regular
116Moose user.
117
118If you wish to use features at this depth, please come to the
119#moose IRC channel on irc.perl.org and we can talk :)
120
6bf30233 121=head1 METHODS
122
123=over 4
124
125=item B<meta>
126
a27aa600 127=item B<new>
128
a27aa600 129=item B<compile_type_coercion>
130
6ba6d68c 131=item B<coerce>
132
a27aa600 133=item B<type_coercion_map>
134
135=item B<type_constraint>
136
41e007e4 137=item B<has_coercion_for_type>
138
139=item B<add_type_coercions>
140
6bf30233 141=back
142
143=head1 BUGS
144
145All complex software has bugs lurking in it, and this module is no
146exception. If you find a bug please either email me, or add the bug
147to cpan-RT.
148
149=head1 AUTHOR
150
151Stevan Little E<lt>stevan@iinteractive.comE<gt>
152
153=head1 COPYRIGHT AND LICENSE
154
2840a3b2 155Copyright 2006-2009 by Infinity Interactive, Inc.
6bf30233 156
157L<http://www.iinteractive.com>
158
159This library is free software; you can redistribute it and/or modify
160it under the same terms as Perl itself.
161
42bc21a4 162=cut