1 package Moose::Meta::Role::Composite;
7 use Scalar::Util 'blessed';
10 $VERSION = eval $VERSION;
11 our $AUTHORITY = 'cpan:STEVAN';
13 use base 'Moose::Meta::Role';
16 # we need to override the ->name
17 # method from Class::MOP::Package
18 # since we don't have an actual
21 __PACKAGE__->meta->add_attribute('name' => (reader => 'name'));
24 # Again, since we don't have a real
25 # package to store our methods in,
26 # we use a HASH ref instead.
28 __PACKAGE__->meta->add_attribute('_methods' => (
29 reader => '_method_map',
33 __PACKAGE__->meta->add_attribute(
34 'application_role_summation_class',
35 reader => 'application_role_summation_class',
36 default => 'Moose::Meta::Role::Application::RoleSummation',
40 my ($class, %params) = @_;
42 # the roles param is required ...
43 foreach ( @{$params{roles}} ) {
44 unless ( $_->isa('Moose::Meta::Role') ) {
46 Moose->throw_error("The list of roles must be instances of Moose::Meta::Role, not $_");
50 my @composition_roles = map {
51 $_->composition_class_roles
52 } @{ $params{roles} };
54 if (@composition_roles) {
55 my $meta = Moose::Meta::Class->create_anon_class(
56 superclasses => [ $class ],
57 roles => [ @composition_roles ],
60 $meta->add_method(meta => sub { $meta });
64 # and the name is created from the
65 # roles if one has not been provided
66 $params{name} ||= (join "|" => map { $_->name } @{$params{roles}});
67 $class->_new(\%params);
70 # This is largely a cope of what's in Moose::Meta::Role (itself
71 # largely a copy of Class::MOP::Class). However, we can't actually
72 # call add_package_symbol, because there's no package to which which
75 my ($self, $method_name, $method) = @_;
77 unless ( defined $method_name && $method_name ) {
78 Moose->throw_error("You must define a method name");
82 if (blessed($method)) {
83 $body = $method->body;
84 if ($method->package_name ne $self->name) {
85 $method = $method->clone(
86 package_name => $self->name,
88 ) if $method->can('clone');
93 $method = $self->wrap_method_body( body => $body, name => $method_name );
96 $self->_method_map->{$method_name} = $method;
101 return keys %{ $self->_method_map };
105 my ($self, $method_name) = @_;
107 return exists $self->_method_map->{$method_name};
111 my ($self, $method_name) = @_;
113 return $self->_method_map->{$method_name};
117 my ($self, $role_params) = @_;
118 Class::MOP::load_class($self->application_role_summation_class);
120 $self->application_role_summation_class->new(
121 role_params => $role_params,
128 my ($class, $old_meta, @args) = @_;
129 Moose->throw_error('Moose::Meta::Role::Composite instances can only be reinitialized from an existing metaclass instance')
130 if !blessed $old_meta || !$old_meta->isa('Moose::Meta::Role::Composite');
131 return $old_meta->meta->clone_object($old_meta, @args);
142 Moose::Meta::Role::Composite - An object to represent the set of roles
146 A composite is a role that consists of a set of two or more roles.
148 The API of a composite role is almost identical to that of a regular
153 C<Moose::Meta::Role::Composite> is a subclass of L<Moose::Meta::Role>.
159 =item B<< Moose::Meta::Role::Composite->new(%options) >>
161 This returns a new composite role object. It accepts the same
162 options as its parent class, with a few changes:
168 This option is an array reference containing a list of
169 L<Moose::Meta::Role> object. This is a required option.
173 If a name is not given, one is generated from the roles provided.
175 =item * apply_params(\%role_params)
177 Creates a new RoleSummation role application with C<%role_params> and applies
178 the composite role to it. The RoleSummation role application class used is
179 determined by the composite role's C<application_role_summation_class>
182 =item * reinitialize($metaclass)
184 Like C<< Class::MOP::Package->reinitialize >>, but doesn't allow passing a
185 string with the package name, as there is no real package for composite roles.
193 All complex software has bugs lurking in it, and this module is no
194 exception. If you find a bug please either email me, or add the bug
199 Stevan Little E<lt>stevan@iinteractive.comE<gt>
201 =head1 COPYRIGHT AND LICENSE
203 Copyright 2006-2009 by Infinity Interactive, Inc.
205 L<http://www.iinteractive.com>
207 This library is free software; you can redistribute it and/or modify
208 it under the same terms as Perl itself.