Add built local::lib
[catagits/Gitalist.git] / local-lib5 / lib / perl5 / Moose / Meta / TypeCoercion.pm
CommitLineData
3fea05b9 1
2package Moose::Meta::TypeCoercion;
3
4use strict;
5use warnings;
6use metaclass;
7
8use Moose::Meta::Attribute;
9use Moose::Util::TypeConstraints ();
10
11our $VERSION = '0.93';
12$VERSION = eval $VERSION;
13our $AUTHORITY = 'cpan:STEVAN';
14
15__PACKAGE__->meta->add_attribute('type_coercion_map' => (
16 reader => 'type_coercion_map',
17 default => sub { [] }
18));
19
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::MOP::class_of($class)->new_object(@_);
35 $self->compile_type_coercion;
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);
45 my $type_constraint = ref $constraint_name ? $constraint_name : Moose::Util::TypeConstraints::find_or_parse_type_constraint($constraint_name);
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
52 push @coercions => [
53 $type_constraint->_compiled_type_constraint,
54 $action
55 ];
56 }
57 $self->_compiled_type_coercion(sub {
58 my $thing = shift;
59 foreach my $coercion (@coercions) {
60 my ($constraint, $converter) = @$coercion;
61 if ($constraint->($thing)) {
62 local $_ = $thing;
63 return $converter->($thing);
64 }
65 }
66 return $thing;
67 });
68}
69
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);
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
90 push @{$coercion_map} => ($constraint_name, $action);
91 }
92
93 # and re-compile ...
94 $self->compile_type_coercion;
95}
96
97sub coerce { $_[0]->_compiled_type_coercion->($_[1]) }
98
99
1001;
101
102__END__
103
104=pod
105
106=head1 NAME
107
108Moose::Meta::TypeCoercion - The Moose Type Coercion metaclass
109
110=head1 DESCRIPTION
111
112A type coercion object is basically a mapping of one or more type
113constraints and the associated coercions subroutines.
114
115It's unlikely that you will need to instantiate an object of this
116class directly, as it's part of the deep internals of Moose.
117
118=head1 METHODS
119
120=over 4
121
122=item B<< Moose::Meta::TypeCoercion->new(%options) >>
123
124Creates a new type coercion object, based on the options provided.
125
126=over 8
127
128=item * type_constraint
129
130This is the L<Moose::Meta::TypeConstraint> object for the type that is
131being coerced I<to>.
132
133=back
134
135=item B<< $coercion->type_coercion_map >>
136
137This returns the map of type constraints to coercions as an array
138reference. The values of the array alternate between type names and
139subroutine references which implement the coercion.
140
141The value is an array reference because coercions are tried in the
142order they are added.
143
144=item B<< $coercion->type_constraint >>
145
146This returns the L<Moose::Meta::TypeConstraint> that was passed to the
147constructor.
148
149=item B<< $coercion->has_coercion_for_type($type_name) >>
150
151Returns true if the coercion can coerce the named type.
152
153=item B<< $coercion->add_type_coercions( $type_name => $sub, ... ) >>
154
155This method takes a list of type names and subroutine references. If
156the coercion already has a mapping for a given type, it throws an
157exception.
158
159Coercions are actually
160
161=item B<< $coercion->coerce($value) >>
162
163This method takes a value and applies the first valid coercion it
164finds.
165
166This means that if the value could belong to more than type in the
167coercion object, the first coercion added is used.
168
169=item B<< Moose::Meta::TypeCoercion->meta >>
170
171This will return a L<Class::MOP::Class> instance for this class.
172
173=back
174
175=head1 BUGS
176
177All complex software has bugs lurking in it, and this module is no
178exception. If you find a bug please either email me, or add the bug
179to cpan-RT.
180
181=head1 AUTHOR
182
183Stevan Little E<lt>stevan@iinteractive.comE<gt>
184
185=head1 COPYRIGHT AND LICENSE
186
187Copyright 2006-2009 by Infinity Interactive, Inc.
188
189L<http://www.iinteractive.com>
190
191This library is free software; you can redistribute it and/or modify
192it under the same terms as Perl itself.
193
194=cut