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 ) = @_;
131 'Moose::Meta::Role::Composite instances can only be reinitialized from an existing metaclass instance'
133 if !blessed $old_meta
134 || !$old_meta->isa('Moose::Meta::Role::Composite');
136 my %existing_classes = map { $_ => $old_meta->$_() } qw(
137 application_role_summation_class
140 return $old_meta->meta->clone_object( $old_meta, %existing_classes, @args );
151 Moose::Meta::Role::Composite - An object to represent the set of roles
155 A composite is a role that consists of a set of two or more roles.
157 The API of a composite role is almost identical to that of a regular
162 C<Moose::Meta::Role::Composite> is a subclass of L<Moose::Meta::Role>.
168 =item B<< Moose::Meta::Role::Composite->new(%options) >>
170 This returns a new composite role object. It accepts the same
171 options as its parent class, with a few changes:
177 This option is an array reference containing a list of
178 L<Moose::Meta::Role> object. This is a required option.
182 If a name is not given, one is generated from the roles provided.
184 =item * apply_params(\%role_params)
186 Creates a new RoleSummation role application with C<%role_params> and applies
187 the composite role to it. The RoleSummation role application class used is
188 determined by the composite role's C<application_role_summation_class>
191 =item * reinitialize($metaclass)
193 Like C<< Class::MOP::Package->reinitialize >>, but doesn't allow passing a
194 string with the package name, as there is no real package for composite roles.
202 All complex software has bugs lurking in it, and this module is no
203 exception. If you find a bug please either email me, or add the bug
208 Stevan Little E<lt>stevan@iinteractive.comE<gt>
210 =head1 COPYRIGHT AND LICENSE
212 Copyright 2006-2010 by Infinity Interactive, Inc.
214 L<http://www.iinteractive.com>
216 This library is free software; you can redistribute it and/or modify
217 it under the same terms as Perl itself.