1 package MooseX::Role::Parameterized::Meta::Role::Parameterizable;
3 extends 'Moose::Meta::Role';
7 use MooseX::Role::Parameterized::Meta::Role::Parameterized;
8 use MooseX::Role::Parameterized::Meta::Parameter;
9 use MooseX::Role::Parameterized::Parameters;
11 use constant parameterized_role_metaclass => 'MooseX::Role::Parameterized::Meta::Role::Parameterized';
12 use constant parameter_metaclass => 'MooseX::Role::Parameterized::Meta::Parameter';
14 has parameters_class => (
17 default => 'MooseX::Role::Parameterized::Parameters',
20 has parameters_metaclass => (
22 isa => 'Moose::Meta::Class',
27 $self->parameters_class->meta->create_anon_class(
28 superclasses => [$self->parameters_class],
29 attribute_metaclass => $self->parameter_metaclass,
33 has_parameter => 'has_attribute',
37 has role_generator => (
40 predicate => 'has_role_generator',
47 confess "You must provide a name for the parameter"
50 # need to figure out a plan for these guys..
51 confess "The parameter name ($name) is currently forbidden"
53 || $name eq 'excludes';
55 $self->parameters_metaclass->add_attribute($name => @_);
58 sub construct_parameters {
62 # need to figure out a plan for these guys..
63 for my $name ('alias', 'excludes') {
64 confess "The parameter name ($name) is currently forbidden"
65 if exists $args{$name};
68 $self->parameters_metaclass->new_object(\%args);
75 my $parameters = blessed($args{parameters})
77 : $self->construct_parameters(%{ $args{parameters} });
79 confess "A role generator is required to generate roles"
80 unless $self->has_role_generator;
82 my $role = $self->parameterized_role_metaclass->create_anon_role(
84 parameters => $parameters,
87 local $MooseX::Role::Parameterized::CURRENT_METACLASS = $role;
89 $self->apply_parameterizable_role($role);
91 $self->role_generator->($parameters,
92 operating_on => $role,
93 consumer => $args{consumer},
99 sub _role_for_combination {
101 my $parameters = shift;
103 return $self->generate_role(
104 parameters => $parameters,
110 my $consumer = shift;
113 my $role = $self->generate_role(
114 consumer => $consumer,
115 parameters => \%args,
118 $role->apply($consumer, %args);
121 sub apply_parameterizable_role {
124 $self->SUPER::apply(@_);
127 __PACKAGE__->meta->make_immutable;
136 MooseX::Role::Parameterized::Meta::Role::Parameterizable - metaclass for parameterizable roles
140 This is the metaclass for parameterizable roles, roles that have their
141 parameters currently unbound. These are the roles that you use L<Moose/with>,
142 but instead of composing the parameterizable role, we construct a new
144 (L<MooseX::Role::Parameterized::Meta::Role::Parameterized>).
148 =head2 parameters_class
150 The name of the class that will be used to construct the parameters object.
152 =head2 parameters_metaclass
154 A metaclass representing this roles's parameters. It will be an anonymous
155 subclass of L</parameters_class>. Each call to
156 L<MooseX::Role::Parameters/parameter> adds an attribute to this metaclass.
158 When this role is consumed, the parameters object will be instantiated using
161 =head2 role_generator
163 A code reference that is used to generate a role based on the parameters
164 provided by the consumer. The user usually specifies it using the
165 L<MooseX::Role::Parameterized/role> keyword.
169 =head2 add_parameter $name, %options
171 Basically delegates to L<Moose::Meta::Class/add_attribute> on the
172 L</parameters_metaclass> but with error messages that refer to a "parameter"
175 =head2 construct_parameters %arguments
177 Creates a new L<MooseX::Role::Parameterized::Parameters> object using metaclass
178 L</parameters_metaclass>.
180 The arguments are those specified by the consumer as parameter values.
182 =head2 generate_role %arguments
184 Returns a new instance of
185 L<MooseX::Role::Parameterized::Meta::Role::Parameterized> based on the
186 arguments. The arguments are a hash reference of C<parameters> and, if
187 available, a C<consumer> metaobject.
191 Overrides L<Moose::Meta::Role/apply> to automatically generate the