File Coverage

blib/lib/Moose/Meta/Role/Composite.pm
Criterion Covered Total %
statement 73 78 93.5
branch 12 16 75.0
condition 6 12 50.0
subroutine 19 20 95.0
pod 11 13 84.6
total 121 139 87.0


line stmt bran cond sub pod time code
1             package Moose::Meta::Role::Composite;
2             our $VERSION = '2.2203';
3              
4 388     388   2714 use strict;
  388         880  
  388         12125  
5 388     388   2216 use warnings;
  388         1616  
  388         9179  
6 388     388   1823 use metaclass;
  388         773  
  388         2213  
7              
8 388     388   2790 use Scalar::Util 'blessed';
  388         842  
  388         20729  
9 388     388   19194 use Moose::Util 'throw_exception';
  388         941  
  388         2837  
10 388     388   96449 use parent 'Moose::Meta::Role';
  388         906  
  388         2162  
11              
12             # NOTE:
13             # we need to override the ->name
14             # method from Class::MOP::Package
15             # since we don't have an actual
16             # package for this.
17             # - SL
18             __PACKAGE__->meta->add_attribute('name' => (
19             reader => 'name',
20             Class::MOP::_definition_context(),
21             ));
22              
23             # NOTE:
24             # Again, since we don't have a real
25             # package to store our methods in,
26             # we use a HASH ref instead.
27             # - SL
28             __PACKAGE__->meta->add_attribute('_methods' => (
29             reader => '_method_map',
30             default => sub { {} },
31             Class::MOP::_definition_context(),
32             ));
33              
34             __PACKAGE__->meta->add_attribute('_overloads' => (
35             reader => '_overload_map',
36             default => sub { {} },
37             Class::MOP::_definition_context(),
38             ));
39              
40             __PACKAGE__->meta->add_attribute('_overload_fallback' => (
41             accessor => '_overload_fallback',
42             Class::MOP::_definition_context(),
43             ));
44              
45             __PACKAGE__->meta->add_attribute(
46             'application_role_summation_class',
47             reader => 'application_role_summation_class',
48             default => 'Moose::Meta::Role::Application::RoleSummation',
49             Class::MOP::_definition_context(),
50             );
51              
52             sub new {
53 259     259 1 1341 my ($class, %params) = @_;
54              
55             # the roles param is required ...
56 259         561 foreach ( @{$params{roles}} ) {
  259         869  
57 582 100       1911 unless ( $_->isa('Moose::Meta::Role') ) {
58 1         6 throw_exception( RolesListMustBeInstancesOfMooseMetaRole => params => \%params,
59             role => $_,
60             class => $class
61             );
62             }
63             }
64              
65             my @composition_roles = map {
66 581         1364 $_->composition_class_roles
67 258         536 } @{ $params{roles} };
  258         684  
68              
69 258 100       856 if (@composition_roles) {
70 3         12 my $meta = Moose::Meta::Class->create_anon_class(
71             superclasses => [ $class ],
72             roles => [ @composition_roles ],
73             cache => 1,
74             );
75 3         12 $class = $meta->name;
76             }
77              
78             # and the name is created from the
79             # roles if one has not been provided
80 258   33     1335 $params{name} ||= (join "|" => map { $_->name } @{$params{roles}});
  581         2742  
  258         564  
81 258         8765 $class->_new(\%params);
82             }
83              
84             # There's no such thing as an anonymous composite role since composites are an
85             # artifact of Moose's internals. However, a composite role that contains an
86             # anon role may _look_ like an anon role since $self->name =~ /$anon_key/ can
87             # return true if the first role in the composite is anonymous itself.
88 61     61 1 1846 sub is_anon { 0 }
89              
90             # This is largely a copy of what's in Moose::Meta::Role (itself
91             # largely a copy of Class::MOP::Class). However, we can't actually
92             # call add_package_symbol, because there's no package into which to
93             # add the symbol.
94             sub add_method {
95 1502     1502 1 3069 my ($self, $method_name, $method) = @_;
96              
97 1502 100 66     5186 unless ( defined $method_name && $method_name ) {
98 1         5 throw_exception( MustDefineAMethodName => instance => $self );
99             }
100              
101 1501         1925 my $body;
102 1501 50       4024 if (blessed($method)) {
103 1501         3583 $body = $method->body;
104 1501 50       37452 if ($method->package_name ne $self->name) {
105 1501 50       37614 $method = $method->clone(
106             package_name => $self->name,
107             name => $method_name
108             ) if $method->can('clone');
109             }
110             }
111             else {
112 0         0 $body = $method;
113 0         0 $method = $self->wrap_method_body( body => $body, name => $method_name );
114             }
115              
116 1501         43342 $self->_method_map->{$method_name} = $method;
117             }
118              
119             sub get_method_list {
120 4     4 1 2028 my $self = shift;
121 4         8 return keys %{ $self->_method_map };
  4         132  
122             }
123              
124             sub _get_local_methods {
125 200     200   449 my $self = shift;
126 200         360 return values %{ $self->_method_map };
  200         6133  
127             }
128              
129             sub has_method {
130 498     498 1 855 my ($self, $method_name) = @_;
131              
132 498         13624 return exists $self->_method_map->{$method_name};
133             }
134              
135             sub get_method {
136 0     0 1 0 my ($self, $method_name) = @_;
137              
138 0         0 return $self->_method_map->{$method_name};
139             }
140              
141             sub is_overloaded {
142 200     200 1 988 my ($self) = @_;
143 200         352 return keys %{ $self->_overload_map };
  200         6544  
144             }
145              
146             sub add_overloaded_operator {
147 4     4 1 15 my ( $self, $op_name, $overload ) = @_;
148              
149 4 50 33     25 unless ( defined $op_name && $op_name ) {
150 0         0 throw_exception(
151             'MustDefineAnOverloadOperator',
152             instance => $self,
153             );
154             }
155              
156 4         155 $self->_overload_map->{$op_name} = $overload;
157             }
158              
159             sub get_overload_fallback_value {
160 4     4 0 12 my ($self) = @_;
161 4         121 return $self->_overload_fallback;
162             }
163              
164             sub set_overload_fallback_value {
165 8     8 0 16 my $self = shift;
166 8         265 $self->_overload_fallback(shift);
167             }
168              
169             sub get_all_overloaded_operators {
170 4     4 1 13 my ( $self, $method_name ) = @_;
171 4         7 return values %{ $self->_overload_map };
  4         122  
172             }
173              
174             sub apply_params {
175 231     231 1 679 my ($self, $role_params) = @_;
176 231         7057 Moose::Util::_load_user_class($self->application_role_summation_class);
177              
178 231         18858 $self->application_role_summation_class->new(
179             role_params => $role_params,
180             )->apply($self);
181              
182 216         2840 return $self;
183             }
184              
185             sub reinitialize {
186 4     4 1 68 my ( $class, $old_meta, @args ) = @_;
187              
188 4 100 66     26 throw_exception( CannotInitializeMooseMetaRoleComposite => old_meta => $old_meta,
189             args => \@args,
190             role_composite => $class
191             )
192             if !blessed $old_meta
193             || !$old_meta->isa('Moose::Meta::Role::Composite');
194              
195 3         8 my %existing_classes = map { $_ => $old_meta->$_() } qw(
  3         91  
196             application_role_summation_class
197             );
198              
199 3         9 return $old_meta->meta->clone_object( $old_meta, %existing_classes, @args );
200             }
201              
202             1;
203              
204             # ABSTRACT: An object to represent the set of roles
205              
206             __END__
207              
208             =pod
209              
210             =encoding UTF-8
211              
212             =head1 NAME
213              
214             Moose::Meta::Role::Composite - An object to represent the set of roles
215              
216             =head1 VERSION
217              
218             version 2.2203
219              
220             =head1 DESCRIPTION
221              
222             A composite is a role that consists of a set of two or more roles.
223              
224             The API of a composite role is almost identical to that of a regular
225             role.
226              
227             =head1 INHERITANCE
228              
229             C<Moose::Meta::Role::Composite> is a subclass of L<Moose::Meta::Role>.
230              
231             =head1 METHODS
232              
233             =head2 Moose::Meta::Role::Composite->new(%options)
234              
235             This returns a new composite role object. It accepts the same
236             options as its parent class, with a few changes:
237              
238             =over 4
239              
240             =item * roles
241              
242             This option is an array reference containing a list of
243             L<Moose::Meta::Role> object. This is a required option.
244              
245             =item * name
246              
247             If a name is not given, one is generated from the roles provided.
248              
249             =item * apply_params(\%role_params)
250              
251             Creates a new RoleSummation role application with C<%role_params> and applies
252             the composite role to it. The RoleSummation role application class used is
253             determined by the composite role's C<application_role_summation_class>
254             attribute.
255              
256             =item * reinitialize($metaclass)
257              
258             Like C<< Class::MOP::Package->reinitialize >>, but doesn't allow passing a
259             string with the package name, as there is no real package for composite roles.
260              
261             =back
262              
263             =head1 BUGS
264              
265             See L<Moose/BUGS> for details on reporting bugs.
266              
267             =head1 AUTHORS
268              
269             =over 4
270              
271             =item *
272              
273             Stevan Little <stevan@cpan.org>
274              
275             =item *
276              
277             Dave Rolsky <autarch@urth.org>
278              
279             =item *
280              
281             Jesse Luehrs <doy@cpan.org>
282              
283             =item *
284              
285             Shawn M Moore <sartak@cpan.org>
286              
287             =item *
288              
289             יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
290              
291             =item *
292              
293             Karen Etheridge <ether@cpan.org>
294              
295             =item *
296              
297             Florian Ragwitz <rafl@debian.org>
298              
299             =item *
300              
301             Hans Dieter Pearcey <hdp@cpan.org>
302              
303             =item *
304              
305             Chris Prather <chris@prather.org>
306              
307             =item *
308              
309             Matt S Trout <mstrout@cpan.org>
310              
311             =back
312              
313             =head1 COPYRIGHT AND LICENSE
314              
315             This software is copyright (c) 2006 by Infinity Interactive, Inc.
316              
317             This is free software; you can redistribute it and/or modify it under
318             the same terms as the Perl 5 programming language system itself.
319              
320             =cut