Change the API of generate_role to a hash so we can specify more
[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,
1e750b62 80 );
4534bdce 81
1e750b62 82 return $role;
4534bdce 83}
84
d872e120 85sub apply {
1a8744bd 86 my $self = shift;
87 my $consumer = shift;
88 my %args = @_;
89
90 my $role = $self->generate_role(
91 consumer => $consumer,
92 parameters => \%args,
93 );
d872e120 94
1a8744bd 95 $role->apply($consumer, %args);
d872e120 96}
97
4a2212da 98sub apply_parameterizable_role {
563f6b7c 99 my $self = shift;
100
101 $self->SUPER::apply(@_);
102}
103
7b42fc96 104__PACKAGE__->meta->make_immutable;
105no Moose;
106
1071;
108
09e02a3f 109__END__
110
30788701 111=head1 NAME
112
113MooseX::Role::Parameterized::Meta::Role::Parameterizable - metaclass for parameterizable roles
114
09e02a3f 115=head1 DESCRIPTION
116
117This is the metaclass for parameteriz-able roles, roles that have their
118parameters currently unbound. These are the roles that you use L<Moose/with>,
119but instead of composing the parameteriz-able role, we construct a new
120parameteriz-ed role
121(L<MooseX::Role::Parameterized::Meta::Role::Parameterized>).
122
123=cut
124