ef6d680292706e9bfcacc18b6d4581ee0da0911d
[gitmo/Moose.git] / lib / Moose / Meta / TypeCoercion.pm
1
2 package Moose::Meta::TypeCoercion;
3
4 use strict;
5 use warnings;
6 use metaclass;
7
8 use Carp 'confess';
9
10 use Moose::Meta::Attribute;
11 use Moose::Util::TypeConstraints ();
12
13 our $VERSION = '0.01';
14
15 __PACKAGE__->meta->add_attribute('type_coercion_map' => (
16     reader  => 'type_coercion_map',
17     default => sub { [] }
18 ));
19 __PACKAGE__->meta->add_attribute(
20     Moose::Meta::Attribute->new('type_constraint' => (
21         reader   => 'type_constraint',
22         weak_ref => 1
23     ))
24 );
25
26 # private accessor
27 __PACKAGE__->meta->add_attribute('compiled_type_coercion' => (
28     accessor => '_compiled_type_coercion'
29 ));
30
31 sub new { 
32     my $class = shift;
33     my $self  = $class->meta->new_object(@_);
34     $self->compile_type_coercion();
35     return $self;
36 }
37
38 sub compile_type_coercion {
39     my $self = shift;
40     my @coercion_map = @{$self->type_coercion_map};
41     my @coercions;
42     while (@coercion_map) {
43         my ($constraint_name, $action) = splice(@coercion_map, 0, 2);
44         my $constraint = Moose::Util::TypeConstraints::find_type_constraint($constraint_name)->_compiled_type_constraint;       
45         (defined $constraint)
46             || confess "Could not find the type constraint ($constraint_name)";
47         push @coercions => [ $constraint, $action ];
48     }
49     $self->_compiled_type_coercion(sub { 
50         my $thing = shift;
51         foreach my $coercion (@coercions) {
52             my ($constraint, $converter) = @$coercion;
53             if (defined $constraint->($thing)) {
54                             local $_ = $thing;                
55                 return $converter->($thing);
56             }
57         }
58         return $thing;
59     });    
60 }
61
62 sub coerce { $_[0]->_compiled_type_coercion->($_[1]) }
63
64
65 1;
66
67 __END__
68
69 =pod
70
71 =head1 NAME
72
73 Moose::Meta::TypeCoercion - The Moose Type Coercion metaclass
74
75 =head1 DESCRIPTION
76
77 For the most part, the only time you will ever encounter an 
78 instance of this class is if you are doing some serious deep 
79 introspection. This API should not be considered final, but 
80 it is B<highly unlikely> that this will matter to a regular 
81 Moose user.
82
83 If you wish to use features at this depth, please come to the 
84 #moose IRC channel on irc.perl.org and we can talk :)
85
86 =head1 METHODS
87
88 =over 4
89
90 =item B<meta>
91
92 =item B<new>
93
94 =item B<compile_type_coercion>
95
96 =item B<coerce>
97
98 =item B<type_coercion_map>
99
100 =item B<type_constraint>
101
102 =back
103
104 =head1 BUGS
105
106 All complex software has bugs lurking in it, and this module is no 
107 exception. If you find a bug please either email me, or add the bug
108 to cpan-RT.
109
110 =head1 AUTHOR
111
112 Stevan Little E<lt>stevan@iinteractive.comE<gt>
113
114 =head1 COPYRIGHT AND LICENSE
115
116 Copyright 2006 by Infinity Interactive, Inc.
117
118 L<http://www.iinteractive.com>
119
120 This library is free software; you can redistribute it and/or modify
121 it under the same terms as Perl itself. 
122
123 =cut