Add role_for_combination to fix prole-role combination
[gitmo/MooseX-Role-Parameterized.git] / lib / MooseX / Role / Parameterized / Meta / Role / Parameterizable.pm
CommitLineData
d93bd54d 1package MooseX::Role::Parameterized::Meta::Role::Parameterizable;
7b42fc96 2use Moose;
3extends 'Moose::Meta::Role';
4
8f9a5c92 5use MooseX::Role::Parameterized::Meta::Role::Parameterized;
1b0f24fa 6use MooseX::Role::Parameterized::Meta::Parameter;
7b42fc96 7use MooseX::Role::Parameterized::Parameters;
8
533553a0 9use constant parameterized_role_metaclass => 'MooseX::Role::Parameterized::Meta::Role::Parameterized';
1b0f24fa 10use constant parameter_metaclass => 'MooseX::Role::Parameterized::Meta::Parameter';
11use constant parameters_class => 'MooseX::Role::Parameterized::Parameters';
533553a0 12
f8f36548 13has parameters_metaclass => (
39d3d5d0 14 is => 'rw',
f563c3cd 15 isa => 'Moose::Meta::Class',
16 lazy => 1,
17 default => sub {
1b0f24fa 18 my $self = shift;
19
20 $self->parameters_class->meta->create_anon_class(
21 superclasses => [$self->parameters_class],
22 attribute_metaclass => $self->parameter_metaclass,
f563c3cd 23 );
24 },
25);
26
5b82ffb1 27has role_generator => (
28 is => 'rw',
29 isa => 'CodeRef',
30 predicate => 'has_role_generator',
31);
32
f563c3cd 33sub add_parameter {
34 my $self = shift;
21c3ef8c 35 my $name = shift;
36
396466d4 37 confess "You must provide a name for the parameter"
38 if !defined($name);
39
21c3ef8c 40 # need to figure out a plan for these guys..
e039cb6c 41 confess "The parameter name ($name) is currently forbidden"
21c3ef8c 42 if $name eq 'alias'
43 || $name eq 'excludes';
44
f8f36548 45 $self->parameters_metaclass->add_attribute($name => @_);
f563c3cd 46}
7b42fc96 47
f74750fb 48sub construct_parameters {
49 my $self = shift;
21c3ef8c 50 my %args = @_;
51
52 # need to figure out a plan for these guys..
53 for my $name ('alias', 'excludes') {
e039cb6c 54 confess "The parameter name ($name) is currently forbidden"
21c3ef8c 55 if exists $args{$name};
56 }
57
f8f36548 58 $self->parameters_metaclass->new_object(\%args);
f74750fb 59}
60
4534bdce 61sub generate_role {
1a8744bd 62 my $self = shift;
63 my %args = @_;
58954f3e 64
1a8744bd 65 my $parameters = blessed($args{parameters})
66 ? $args{parameters}
67 : $self->construct_parameters(%{ $args{parameters} });
4534bdce 68
69 confess "A role generator is required to generate roles"
70 unless $self->has_role_generator;
71
533553a0 72 my $role = $self->parameterized_role_metaclass->create_anon_role(parameters => $parameters);
4534bdce 73
884a2a3b 74 local $MooseX::Role::Parameterized::CURRENT_METACLASS = $role;
563f6b7c 75
4a2212da 76 $self->apply_parameterizable_role($role);
563f6b7c 77
1e750b62 78 $self->role_generator->($parameters,
884a2a3b 79 operating_on => $role,
44e155fd 80 consumer => $args{consumer},
1e750b62 81 );
4534bdce 82
1e750b62 83 return $role;
4534bdce 84}
85
592ff67c 86sub role_for_combination {
87 my $self = shift;
88 my $parameters = shift;
89
90 return $self->generate_role(
91 parameters => $parameters,
92 );
93}
94
d872e120 95sub apply {
1a8744bd 96 my $self = shift;
97 my $consumer = shift;
98 my %args = @_;
99
100 my $role = $self->generate_role(
101 consumer => $consumer,
102 parameters => \%args,
103 );
d872e120 104
1a8744bd 105 $role->apply($consumer, %args);
d872e120 106}
107
4a2212da 108sub apply_parameterizable_role {
563f6b7c 109 my $self = shift;
110
111 $self->SUPER::apply(@_);
112}
113
7b42fc96 114__PACKAGE__->meta->make_immutable;
115no Moose;
116
1171;
118
09e02a3f 119__END__
120
30788701 121=head1 NAME
122
123MooseX::Role::Parameterized::Meta::Role::Parameterizable - metaclass for parameterizable roles
124
09e02a3f 125=head1 DESCRIPTION
126
127This is the metaclass for parameteriz-able roles, roles that have their
128parameters currently unbound. These are the roles that you use L<Moose/with>,
129but instead of composing the parameteriz-able role, we construct a new
130parameteriz-ed role
131(L<MooseX::Role::Parameterized::Meta::Role::Parameterized>).
132
133=cut
134