Use attribute_metaclass in the constructor for parameters_metaclass, and
[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 {
62 my $self = shift;
58954f3e 63
64 my $parameters = @_ == 1 ? shift
65 : $self->construct_parameters(@_);
4534bdce 66
67 confess "A role generator is required to generate roles"
68 unless $self->has_role_generator;
69
533553a0 70 my $role = $self->parameterized_role_metaclass->create_anon_role(parameters => $parameters);
4534bdce 71
884a2a3b 72 local $MooseX::Role::Parameterized::CURRENT_METACLASS = $role;
563f6b7c 73
4a2212da 74 $self->apply_parameterizable_role($role);
563f6b7c 75
1e750b62 76 $self->role_generator->($parameters,
884a2a3b 77 operating_on => $role,
1e750b62 78 );
4534bdce 79
1e750b62 80 return $role;
4534bdce 81}
82
d872e120 83sub apply {
84 my $self = shift;
85 my $class = shift;
86 my %args = @_;
87
88 my $role = $self->generate_role(%args);
89 $role->apply($class, %args);
90}
91
4a2212da 92sub apply_parameterizable_role {
563f6b7c 93 my $self = shift;
94
95 $self->SUPER::apply(@_);
96}
97
7b42fc96 98__PACKAGE__->meta->make_immutable;
99no Moose;
100
1011;
102
09e02a3f 103__END__
104
30788701 105=head1 NAME
106
107MooseX::Role::Parameterized::Meta::Role::Parameterizable - metaclass for parameterizable roles
108
09e02a3f 109=head1 DESCRIPTION
110
111This is the metaclass for parameteriz-able roles, roles that have their
112parameters currently unbound. These are the roles that you use L<Moose/with>,
113but instead of composing the parameteriz-able role, we construct a new
114parameteriz-ed role
115(L<MooseX::Role::Parameterized::Meta::Role::Parameterized>).
116
117=cut
118