type-coercion-meta-object
[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 metaobject
74
75 =head1 SYNOPSIS
76
77 =head1 DESCRIPTION
78
79 =head1 METHODS
80
81 =over 4
82
83 =item B<meta>
84
85 =item B<new>
86
87 =item B<coerce>
88
89 =item B<compile_type_coercion>
90
91 =item B<type_coercion_map>
92
93 =item B<type_constraint>
94
95 =back
96
97 =head1 BUGS
98
99 All complex software has bugs lurking in it, and this module is no 
100 exception. If you find a bug please either email me, or add the bug
101 to cpan-RT.
102
103 =head1 AUTHOR
104
105 Stevan Little E<lt>stevan@iinteractive.comE<gt>
106
107 =head1 COPYRIGHT AND LICENSE
108
109 Copyright 2006 by Infinity Interactive, Inc.
110
111 L<http://www.iinteractive.com>
112
113 This library is free software; you can redistribute it and/or modify
114 it under the same terms as Perl itself. 
115
116 =cut