634f2b90b0d46cff6a46053b2d54a29217fda8f1
[gitmo/MooseX-AttributeHelpers.git] / lib / MooseX / AttributeHelpers / Composite / Trait.pm
1 package MooseX::AttributeHelpers::Composite::Trait;
2 use Moose::Role;
3 use MooseX::AttributeHelpers::MethodProvider;
4 use MooseX::AttributeHelpers::Meta::Method::Provided;
5
6 has provides => (
7     is      => 'ro',
8     isa     => 'HashRef',
9     default => sub { {} },
10 );
11
12 after install_accessors => sub {
13     my $attr  = shift;
14     my $class = $attr->associated_class;
15
16     my $provides = $attr->provides;
17
18     foreach my $method_provider (keys %$provides) {
19         my $typename = get_provider_type($method_provider);
20         confess "Attribute must be of type $typename to use $method_provider"
21             unless ($attr->has_type_constraint
22                     && $attr->type_constraint->is_a_type_of($typename));
23     
24         my $spec = $provides->{$method_provider};
25         my $factories = get_provider_methods($method_provider, $spec);
26
27         foreach my $method_name (keys %$factories) {
28             confess "$method_name already exists in class " . $class->name
29                 if $class->has_method($method_name);
30
31             my $method = MooseX::AttributeHelpers::Meta::Method::Provided->wrap(
32                 $factories->{$method_name}->(
33                     $attr, 
34                     $attr->get_read_method_ref, 
35                     $attr->get_write_method_ref
36                 ),
37             );
38             $attr->associate_method($method);
39             $class->add_method($method_name => $method)
40         }
41     }
42 };
43
44 1;