Allow passing in an already constructed parameter object
[gitmo/MooseX-Role-Parameterized.git] / lib / MooseX / Role / Parameterized / Meta / Role / Parameterizable.pm
1 #!/usr/bin/env perl
2 package MooseX::Role::Parameterized::Meta::Role::Parameterizable;
3 use Moose;
4 extends 'Moose::Meta::Role';
5
6 use MooseX::Role::Parameterized::Meta::Role::Parameterized;
7 use MooseX::Role::Parameterized::Parameters;
8
9 use constant parameterized_role_metaclass => 'MooseX::Role::Parameterized::Meta::Role::Parameterized';
10
11 has parameter_metaclass => (
12     is      => 'rw',
13     isa     => 'Moose::Meta::Class',
14     lazy    => 1,
15     default => sub {
16         Moose::Meta::Class->create_anon_class(
17             superclasses => ['MooseX::Role::Parameterized::Parameters'],
18         );
19     },
20 );
21
22 has role_generator => (
23     is        => 'rw',
24     isa       => 'CodeRef',
25     predicate => 'has_role_generator',
26 );
27
28 sub add_parameter {
29     my $self = shift;
30     $self->parameter_metaclass->add_attribute(@_);
31 }
32
33 sub construct_parameters {
34     my $self = shift;
35     $self->parameter_metaclass->new_object(@_);
36 }
37
38 sub generate_role {
39     my $self = shift;
40
41     my $parameters = @_ == 1 ? shift
42                              : $self->construct_parameters(@_);
43
44     confess "A role generator is required to generate roles"
45         unless $self->has_role_generator;
46
47     my $role = $self->parameterized_role_metaclass->create_anon_role(parameters => $parameters);
48
49     local $MooseX::Role::Parameterized::CURRENT_METACLASS = $role;
50     $self->role_generator->($parameters,
51         operating_on => $role,
52     );
53
54     return $role;
55 }
56
57 sub apply {
58     my $self  = shift;
59     my $class = shift;
60     my %args  = @_;
61
62     my $role = $self->generate_role(%args);
63     $role->apply($class, %args);
64 }
65
66 __PACKAGE__->meta->make_immutable;
67 no Moose;
68
69 1;
70