File Coverage

blib/lib/Moose/Meta/Role.pm
Criterion Covered Total %
statement 201 226 88.9
branch 73 90 81.1
condition 25 48 52.0
subroutine 52 55 94.5
pod 19 20 95.0
total 370 439 84.2


line stmt bran cond sub pod time code
1             package Moose::Meta::Role;
2             our $VERSION = '2.2206';
3              
4 378     378   150516 use strict;
  378         1005  
  378         12769  
5 378     378   2262 use warnings;
  378         968  
  378         9860  
6 378     378   2921 use metaclass;
  378         975  
  378         2448  
7              
8 378     378   3009 use Scalar::Util 'blessed';
  378         1111  
  378         24061  
9              
10 378     378   7624 use Moose::Meta::Class;
  378         1136  
  378         11589  
11 378     378   186859 use Moose::Meta::Role::Attribute;
  378         1294  
  378         15363  
12 378     378   179190 use Moose::Meta::Role::Method;
  378         1185  
  378         13959  
13 378     378   176602 use Moose::Meta::Role::Method::Required;
  378         1215  
  378         13275  
14 378     378   181050 use Moose::Meta::Role::Method::Conflicting;
  378         1237  
  378         15197  
15 378     378   3163 use Moose::Meta::Method::Meta;
  378         984  
  378         10414  
16 378     378   2214 use Moose::Util qw/throw_exception/;
  378         977  
  378         1997  
17 378     378   94575 use Class::MOP::MiniTrait;
  378         1101  
  378         12723  
18              
19 378         2114 use parent 'Class::MOP::Module',
20             'Class::MOP::Mixin::HasAttributes',
21             'Class::MOP::Mixin::HasMethods',
22 378     378   2200 'Class::MOP::Mixin::HasOverloads';
  378         1101  
23              
24             Class::MOP::MiniTrait::apply(__PACKAGE__, 'Moose::Meta::Object::Trait');
25              
26             ## ------------------------------------------------------------------
27             ## NOTE:
28             ## I normally don't do this, but I am doing
29             ## a whole bunch of meta-programmin' in this
30             ## module, so it just makes sense. For a clearer
31             ## picture of what is going on in the next
32             ## several lines of code, look at the really
33             ## big comment at the end of this file (right
34             ## before the POD).
35             ## - SL
36             ## ------------------------------------------------------------------
37              
38             my $META = __PACKAGE__->meta;
39              
40             ## ------------------------------------------------------------------
41             ## attributes ...
42              
43             # NOTE:
44             # since roles are lazy, we hold all the attributes
45             # of the individual role in 'stasis' until which
46             # time when it is applied to a class. This means
47             # keeping a lot of things in hash maps, so we are
48             # using a little of that meta-programmin' magic
49             # here and saving lots of extra typin'. And since
50             # many of these attributes above require similar
51             # functionality to support them, so we again use
52             # the wonders of meta-programmin' to deliver a
53             # very compact solution to this normally verbose
54             # problem.
55             # - SL
56              
57             foreach my $action (
58             {
59             name => 'excluded_roles_map',
60             attr_reader => 'get_excluded_roles_map' ,
61             methods => {
62             add => 'add_excluded_roles',
63             get_keys => 'get_excluded_roles_list',
64             existence => 'excludes_role',
65             }
66             },
67             {
68             name => 'required_methods',
69             attr_reader => 'get_required_methods_map',
70             methods => {
71             remove => 'remove_required_methods',
72             get_values => 'get_required_method_list',
73             existence => 'requires_method',
74             }
75             },
76             ) {
77              
78             my $attr_reader = $action->{attr_reader};
79             my $methods = $action->{methods};
80              
81             # create the attribute
82             $META->add_attribute($action->{name} => (
83             reader => $attr_reader,
84             default => sub { {} },
85             Class::MOP::_definition_context(),
86             ));
87              
88             # create some helper methods
89             $META->add_method($methods->{add} => sub {
90 258     258   998 my ($self, @values) = @_;
91 258         1532 $self->$attr_reader->{$_} = undef foreach @values;
92             }) if exists $methods->{add};
93              
94             $META->add_method($methods->{get_keys} => sub {
95 2199     2199   5532 my ($self) = @_;
96 2199         3510 keys %{$self->$attr_reader};
  2199         74589  
97             }) if exists $methods->{get_keys};
98              
99             $META->add_method($methods->{get_values} => sub {
100 2197     2197   6783 my ($self) = @_;
101 2197         3407 values %{$self->$attr_reader};
  2197         73432  
102             }) if exists $methods->{get_values};
103              
104             $META->add_method($methods->{get} => sub {
105             my ($self, $name) = @_;
106             $self->$attr_reader->{$name}
107             }) if exists $methods->{get};
108              
109             $META->add_method($methods->{existence} => sub {
110 652     652   2811 my ($self, $name) = @_;
        652      
111 652 100       22866 exists $self->$attr_reader->{$name} ? 1 : 0;
112             }) if exists $methods->{existence};
113              
114             $META->add_method($methods->{remove} => sub {
115 0     0   0 my ($self, @values) = @_;
116 0         0 delete $self->$attr_reader->{$_} foreach @values;
117             }) if exists $methods->{remove};
118             }
119              
120             $META->add_attribute(
121             'method_metaclass',
122             reader => 'method_metaclass',
123             default => 'Moose::Meta::Role::Method',
124             Class::MOP::_definition_context(),
125             );
126              
127             $META->add_attribute(
128             'required_method_metaclass',
129             reader => 'required_method_metaclass',
130             default => 'Moose::Meta::Role::Method::Required',
131             Class::MOP::_definition_context(),
132             );
133              
134             $META->add_attribute(
135             'conflicting_method_metaclass',
136             reader => 'conflicting_method_metaclass',
137             default => 'Moose::Meta::Role::Method::Conflicting',
138             Class::MOP::_definition_context(),
139             );
140              
141             $META->add_attribute(
142             'application_to_class_class',
143             reader => 'application_to_class_class',
144             default => 'Moose::Meta::Role::Application::ToClass',
145             Class::MOP::_definition_context(),
146             );
147              
148             $META->add_attribute(
149             'application_to_role_class',
150             reader => 'application_to_role_class',
151             default => 'Moose::Meta::Role::Application::ToRole',
152             Class::MOP::_definition_context(),
153             );
154              
155             $META->add_attribute(
156             'application_to_instance_class',
157             reader => 'application_to_instance_class',
158             default => 'Moose::Meta::Role::Application::ToInstance',
159             Class::MOP::_definition_context(),
160             );
161              
162             $META->add_attribute(
163             'applied_attribute_metaclass',
164             reader => 'applied_attribute_metaclass',
165             default => 'Moose::Meta::Attribute',
166             Class::MOP::_definition_context(),
167             );
168              
169             # More or less copied from Moose::Meta::Class
170             sub initialize {
171 1326     1326 1 4635 my $class = shift;
172 1326         3752 my @args = @_;
173 1326 50       6452 unshift @args, 'package' if @args % 2;
174 1326         5222 my %opts = @args;
175 1326         4876 my $package = delete $opts{package};
176 1326   33     4913 return Class::MOP::get_metaclass_by_name($package)
177             || $class->SUPER::initialize($package,
178             'attribute_metaclass' => 'Moose::Meta::Role::Attribute',
179             %opts,
180             );
181             }
182              
183             sub reinitialize {
184 19     19 1 706 my $self = shift;
185 19         41 my $pkg = shift;
186              
187 19 100       90 my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg);
188              
189 19         68 my %existing_classes;
190 19 50       61 if ($meta) {
191 19         61 %existing_classes = map { $_ => $meta->$_() } qw(
  171         4152  
192             attribute_metaclass
193             method_metaclass
194             wrapped_method_metaclass
195             required_method_metaclass
196             conflicting_method_metaclass
197             application_to_class_class
198             application_to_role_class
199             application_to_instance_class
200             applied_attribute_metaclass
201             );
202             }
203              
204 19         125 my %options = @_;
205             $options{weaken} = Class::MOP::metaclass_is_weak($meta->name)
206             if !exists $options{weaken}
207 19 50 33     305 && blessed($meta)
      33        
208             && $meta->isa('Moose::Meta::Role');
209              
210             # don't need to remove generated metaobjects here yet, since we don't
211             # yet generate anything in roles. this may change in the future though...
212             # keep an eye on that
213 19         176 my $new_meta = $self->SUPER::reinitialize(
214             $pkg,
215             %existing_classes,
216             %options,
217             );
218 19 50 33     297 $new_meta->_restore_metaobjects_from($meta)
219             if $meta && $meta->isa('Moose::Meta::Role');
220 19         163 return $new_meta;
221             }
222              
223             sub _restore_metaobjects_from {
224 19     19   69 my $self = shift;
225 19         51 my ($old_meta) = @_;
226              
227 19         129 $self->_restore_metamethods_from($old_meta);
228 19         131 $self->_restore_metaattributes_from($old_meta);
229              
230 19         44 for my $role ( @{ $old_meta->get_roles } ) {
  19         672  
231 2         14 $self->add_role($role);
232             }
233             }
234              
235             sub add_attribute {
236 732     732 1 1949 my $self = shift;
237              
238 732 100 100     9979 if (blessed $_[0] && ! $_[0]->isa('Moose::Meta::Role::Attribute') ) {
    100 100        
      100        
239 1         4 my $class = ref $_[0];
240 1         12 throw_exception( CannotAddAsAnAttributeToARole => role_name => $self->name,
241             attribute_class => $class,
242             );
243             }
244             elsif (!blessed($_[0]) && defined($_[0]) && $_[0] =~ /^\+(.*)/) {
245 2         29 throw_exception( AttributeExtensionIsNotSupportedInRoles => attribute_name => $_[0],
246             role_name => $self->name,
247             );
248             }
249              
250 729         5321 return $self->SUPER::add_attribute(@_);
251             }
252              
253             sub _attach_attribute {
254 727     727   1888 my ( $self, $attribute ) = @_;
255              
256 727         2947 $attribute->attach_to_role($self);
257             }
258              
259             sub add_required_methods {
260 692     692 1 1487 my $self = shift;
261              
262 692         2376 for (@_) {
263 577         1037 my $method = $_;
264 577 100       2201 if (!blessed($method)) {
265 185         6596 $method = $self->required_method_metaclass->new(
266             name => $method,
267             );
268             }
269 577         19808 $self->get_required_methods_map->{$method->name} = $method;
270             }
271             }
272              
273             sub add_conflicting_method {
274 135     135 1 259 my $self = shift;
275              
276 135         215 my $method;
277 135 50 33     515 if (@_ == 1 && blessed($_[0])) {
278 0         0 $method = shift;
279             }
280             else {
281 135         4461 $method = $self->conflicting_method_metaclass->new(@_);
282             }
283              
284 135         476 $self->add_required_methods($method);
285             }
286              
287             ## ------------------------------------------------------------------
288             ## method modifiers
289              
290             # NOTE:
291             # the before/around/after method modifiers are
292             # stored by name, but there can be many methods
293             # then associated with that name. So again we have
294             # lots of similar functionality, so we can do some
295             # meta-programmin' and save some time.
296             # - SL
297              
298             foreach my $modifier_type (qw[ before around after ]) {
299              
300             my $attr_reader = "get_${modifier_type}_method_modifiers_map";
301              
302             # create the attribute ...
303             $META->add_attribute("${modifier_type}_method_modifiers" => (
304             reader => $attr_reader,
305             default => sub { {} },
306             Class::MOP::_definition_context(),
307             ));
308              
309             # and some helper methods ...
310             $META->add_method("get_${modifier_type}_method_modifiers" => sub {
311 2314     2314   5620 my ($self, $method_name) = @_;
        2314      
        2314      
312             #return () unless exists $self->$attr_reader->{$method_name};
313 2314         81583 my $mm = $self->$attr_reader->{$method_name};
314 2314 100       15126 $mm ? @$mm : ();
315             });
316              
317             $META->add_method("has_${modifier_type}_method_modifiers" => sub {
318 11     11   2428 my ($self, $method_name) = @_;
        11      
        11      
319             # NOTE:
320             # for now we assume that if it exists,..
321             # it has at least one modifier in it
322 11 100       402 (exists $self->$attr_reader->{$method_name}) ? 1 : 0;
323             });
324              
325             $META->add_method("add_${modifier_type}_method_modifier" => sub {
326 1612     1612   3739 my ($self, $method_name, $method) = @_;
        1612      
        1612      
327              
328             $self->$attr_reader->{$method_name} = []
329 1612 100       55006 unless exists $self->$attr_reader->{$method_name};
330              
331 1612         53797 my $modifiers = $self->$attr_reader->{$method_name};
332              
333             # NOTE:
334             # check to see that we aren't adding the
335             # same code twice. We err in favor of the
336             # first on here, this may not be as expected
337 1612         2648 foreach my $modifier (@{$modifiers}) {
  1612         3459  
338 17 100       183 return if $modifier == $method;
339             }
340              
341 1597         2224 push @{$modifiers} => $method;
  1597         6220  
342             });
343              
344             }
345              
346             ## ------------------------------------------------------------------
347             ## override method modifiers
348              
349             $META->add_attribute('override_method_modifiers' => (
350             reader => 'get_override_method_modifiers_map',
351             default => sub { {} },
352             Class::MOP::_definition_context(),
353             ));
354              
355             # NOTE:
356             # these are a little different because there
357             # can only be one per name, whereas the other
358             # method modifiers can have multiples.
359             # - SL
360              
361             sub add_override_method_modifier {
362 1453     1453 1 3065 my ($self, $method_name, $method) = @_;
363 1453 100       4184 (!$self->has_method($method_name))
364             || throw_exception( CannotOverrideALocalMethod => method_name => $method_name,
365             role_name => $self->name,
366             );
367 1451         50873 $self->get_override_method_modifiers_map->{$method_name} = $method;
368             }
369              
370             sub has_override_method_modifier {
371 1051     1051 1 2664 my ($self, $method_name) = @_;
372             # NOTE:
373             # for now we assume that if it exists,..
374             # it has at least one modifier in it
375 1051 100       37188 (exists $self->get_override_method_modifiers_map->{$method_name}) ? 1 : 0;
376             }
377              
378             sub get_override_method_modifier {
379 2301     2301 1 4409 my ($self, $method_name) = @_;
380 2301         82501 $self->get_override_method_modifiers_map->{$method_name};
381             }
382              
383             ## general list accessor ...
384              
385             sub get_method_modifier_list {
386 8426     8426 0 19775 my ($self, $modifier_type) = @_;
387 8426         16661 my $accessor = "get_${modifier_type}_method_modifiers_map";
388 8426         11288 keys %{$self->$accessor};
  8426         308333  
389             }
390              
391 1324     1324   10082 sub _meta_method_class { 'Moose::Meta::Method::Meta' }
392              
393             ## ------------------------------------------------------------------
394             ## subroles
395              
396             $META->add_attribute('roles' => (
397             reader => 'get_roles',
398             default => sub { [] },
399             Class::MOP::_definition_context(),
400             ));
401              
402             sub add_role {
403 501     501 1 1679 my ($self, $role) = @_;
404 501 100 66     4666 (blessed($role) && $role->isa('Moose::Meta::Role'))
405             || throw_exception( AddRoleToARoleTakesAMooseMetaRole => role_to_be_added => $role,
406             role_name => $self->name,
407             );
408 500         1188 push @{$self->get_roles} => $role;
  500         17821  
409 500         2716 $self->reset_package_cache_flag;
410             }
411              
412             sub calculate_all_roles {
413 541     541 1 957 my $self = shift;
414 541         863 my %seen;
415             grep {
416 756         4894 !$seen{$_->name}++
417             } ($self, map {
418 206         867 $_->calculate_all_roles
419 541         894 } @{ $self->get_roles });
  541         14948  
420             }
421              
422             sub does_role {
423 772     772 1 4076 my ($self, $role) = @_;
424 772 100       1696 (defined $role)
425             || throw_exception( RoleNameRequiredForMooseMetaRole => role_name => $self->name );
426 771 100       2175 my $role_name = blessed $role ? $role->name : $role;
427             # if we are it,.. then return true
428 771 100       10604 return 1 if $role_name eq $self->name;
429             # otherwise.. check our children
430 386         607 foreach my $role (@{$self->get_roles}) {
  386         10691  
431 272 100       701 return 1 if $role->does_role($role_name);
432             }
433 225         731 return 0;
434             }
435              
436 1962     1962 1 6526 sub find_method_by_name { (shift)->get_method(@_) }
437              
438             ## ------------------------------------------------------------------
439             ## role construction
440             ## ------------------------------------------------------------------
441              
442             sub apply {
443 1646     1646 1 4454 my ($self, $other, %args) = @_;
444              
445 1646 100       6931 (blessed($other))
446             || throw_exception( ApplyTakesABlessedInstance => param => $other,
447             role_name => $self->name,
448             );
449              
450 1645         3328 my $application_class;
451 1645 100       11349 if ($other->isa('Moose::Meta::Role')) {
    100          
452 505         18670 $application_class = $self->application_to_role_class;
453             }
454             elsif ($other->isa('Moose::Meta::Class')) {
455 1117         40611 $application_class = $self->application_to_class_class;
456             }
457             else {
458 23         884 $application_class = $self->application_to_instance_class;
459             }
460              
461 1645         6440 Moose::Util::_load_user_class($application_class);
462              
463 1645 100       96781 if ( exists $args{'-excludes'} ) {
464             # I wish we had coercion here :)
465             $args{'-excludes'} = (
466             ref $args{'-excludes'} eq 'ARRAY'
467             ? $args{'-excludes'}
468 11 100       57 : [ $args{'-excludes'} ]
469             );
470             }
471              
472 1645         17928 return $application_class->new(%args)->apply($self, $other, \%args);
473             }
474              
475       582 1   sub composition_class_roles { }
476              
477             sub combine {
478 231     231 1 985 my ($class, @role_specs) = @_;
479              
480 231         1511 require Moose::Meta::Role::Composite;
481              
482 231         664 my (@roles, %role_params);
483 231         866 while (@role_specs) {
484 519         909 my ($role, $params) = @{ splice @role_specs, 0, 1 };
  519         1311  
485 519 100       1875 my $requested_role
486             = blessed $role
487             ? $role
488             : Class::MOP::class_of($role);
489              
490 519         1536 my $actual_role = $requested_role->_role_for_combination($params);
491 519         1013 push @roles => $actual_role;
492              
493 519 100       1770 next unless defined $params;
494 29         206 $role_params{$actual_role->name} = $params;
495             }
496              
497 231         2590 my $c = Moose::Meta::Role::Composite->new(roles => \@roles);
498 231         1605 return $c->apply_params(\%role_params);
499             }
500              
501             sub _role_for_combination {
502 518     518   1067 my ($self, $params) = @_;
503 518         933 return $self;
504             }
505              
506             sub create {
507 16     16 1 478 my $class = shift;
508 16         56 my @args = @_;
509              
510 16 50       101 unshift @args, 'package' if @args % 2 == 1;
511 16         65 my %options = @args;
512              
513             (ref $options{attributes} eq 'HASH')
514             || throw_exception( CreateTakesHashRefOfAttributes => params => \%options,
515             attribute_class => $class
516             )
517 16 100 66     70 if exists $options{attributes};
518              
519             (ref $options{methods} eq 'HASH')
520             || throw_exception( CreateTakesHashRefOfMethods => params => \%options,
521             attribute_class => $class
522             )
523 15 100 66     73 if exists $options{methods};
524              
525             (ref $options{roles} eq 'ARRAY')
526             || throw_exception( CreateTakesArrayRefOfRoles => params => \%options,
527             attribute_class => $class
528             )
529 14 100 66     53 if exists $options{roles};
530              
531 13         34 my $package = delete $options{package};
532 13         30 my $roles = delete $options{roles};
533 13         24 my $attributes = delete $options{attributes};
534 13         28 my $methods = delete $options{methods};
535             my $meta_name = exists $options{meta_name}
536             ? delete $options{meta_name}
537 13 50       48 : 'meta';
538              
539 13         86 my $meta = $class->SUPER::create($package => %options);
540              
541 13 50       118 $meta->_add_meta_method($meta_name)
542             if defined $meta_name;
543              
544 13 100       51 if (defined $attributes) {
545 2         8 foreach my $attribute_name (keys %{$attributes}) {
  2         12  
546 2         6 my $attr = $attributes->{$attribute_name};
547             $meta->add_attribute(
548 2 50       26 $attribute_name => blessed $attr ? $attr : %{$attr} );
  2         12  
549             }
550             }
551              
552 13 100       47 if (defined $methods) {
553 7         14 foreach my $method_name (keys %{$methods}) {
  7         28  
554 7         25 $meta->add_method($method_name, $methods->{$method_name});
555             }
556             }
557              
558 13 100       46 if ($roles) {
559 1         5 Moose::Util::apply_all_roles($meta, @$roles);
560             }
561              
562 13         62 return $meta;
563             }
564              
565             sub consumers {
566 3     3 1 7 my $self = shift;
567 3         5 my @consumers;
568 3         10 for my $meta (Class::MOP::get_all_metaclass_instances) {
569 225 100       680 next if $meta->name eq $self->name;
570 222 100 100     891 next unless $meta->isa('Moose::Meta::Class')
571             || $meta->isa('Moose::Meta::Role');
572 21 100       63 push @consumers, $meta->name
573             if $meta->does_role($self->name);
574             }
575 3         47 return @consumers;
576             }
577              
578             # XXX: something more intelligent here?
579 49     49   157 sub _anon_package_prefix { 'Moose::Meta::Role::__ANON__::SERIAL::' }
580              
581 11     11 1 3051 sub create_anon_role { shift->create_anon(@_) }
582 2     2 1 4040 sub is_anon_role { shift->is_anon(@_) }
583              
584             sub _anon_cache_key {
585 0     0     my $class = shift;
586 0           my %options = @_;
587              
588             # XXX fix this duplication (see MMC::_anon_cache_key
589             my $roles = Data::OptList::mkopt(($options{roles} || []), {
590             moniker => 'role',
591 0     0     val_test => sub { ref($_[0]) eq 'HASH' },
592 0   0       });
593              
594 0           my @role_keys;
595 0           for my $role_spec (@$roles) {
596 0           my ($role, $params) = @$role_spec;
597 0           $params = { %$params };
598              
599 0 0         my $key = blessed($role) ? $role->name : $role;
600              
601 0 0 0       if ($params && %$params) {
602             my $alias = delete $params->{'-alias'}
603 0   0       || delete $params->{'alias'}
604             || {};
605             my $excludes = delete $params->{'-excludes'}
606 0   0       || delete $params->{'excludes'}
607             || [];
608 0 0         $excludes = [$excludes] unless ref($excludes) eq 'ARRAY';
609              
610 0 0         if (%$params) {
611 0           warn "Roles with parameters cannot be cached. Consider "
612             . "applying the parameters before calling "
613             . "create_anon_class, or using 'weaken => 0' instead";
614 0           return;
615             }
616              
617             my $alias_key = join('%',
618 0           map { $_ => $alias->{$_} } sort keys %$alias
  0            
619             );
620 0           my $excludes_key = join('%',
621             sort @$excludes
622             );
623 0           $key .= '<' . join('+', 'a', $alias_key, 'e', $excludes_key) . '>';
624             }
625              
626 0           push @role_keys, $key;
627             }
628              
629             # Makes something like Role|Role::1
630 0           return join('|', sort @role_keys);
631             }
632              
633             #####################################################################
634             ## NOTE:
635             ## This is Moose::Meta::Role as defined by Moose (plus the use of
636             ## MooseX::AttributeHelpers module). It is here as a reference to
637             ## make it easier to see what is happening above with all the meta
638             ## programming. - SL
639             #####################################################################
640             #
641             # has 'roles' => (
642             # metaclass => 'Array',
643             # reader => 'get_roles',
644             # isa => 'ArrayRef[Moose::Meta::Role]',
645             # default => sub { [] },
646             # provides => {
647             # 'push' => 'add_role',
648             # }
649             # );
650             #
651             # has 'excluded_roles_map' => (
652             # metaclass => 'Hash',
653             # reader => 'get_excluded_roles_map',
654             # isa => 'HashRef[Str]',
655             # provides => {
656             # # Not exactly set, cause it sets multiple
657             # 'set' => 'add_excluded_roles',
658             # 'keys' => 'get_excluded_roles_list',
659             # 'exists' => 'excludes_role',
660             # }
661             # );
662             #
663             # has 'required_methods' => (
664             # metaclass => 'Hash',
665             # reader => 'get_required_methods_map',
666             # isa => 'HashRef[Moose::Meta::Role::Method::Required]',
667             # provides => {
668             # # not exactly set, or delete since it works for multiple
669             # 'set' => 'add_required_methods',
670             # 'delete' => 'remove_required_methods',
671             # 'keys' => 'get_required_method_list',
672             # 'exists' => 'requires_method',
673             # }
674             # );
675             #
676             # # the before, around and after modifiers are
677             # # HASH keyed by method-name, with ARRAY of
678             # # CODE refs to apply in that order
679             #
680             # has 'before_method_modifiers' => (
681             # metaclass => 'Hash',
682             # reader => 'get_before_method_modifiers_map',
683             # isa => 'HashRef[ArrayRef[CodeRef]]',
684             # provides => {
685             # 'keys' => 'get_before_method_modifiers',
686             # 'exists' => 'has_before_method_modifiers',
687             # # This actually makes sure there is an
688             # # ARRAY at the given key, and pushed onto
689             # # it. It also checks for duplicates as well
690             # # 'add' => 'add_before_method_modifier'
691             # }
692             # );
693             #
694             # has 'after_method_modifiers' => (
695             # metaclass => 'Hash',
696             # reader =>'get_after_method_modifiers_map',
697             # isa => 'HashRef[ArrayRef[CodeRef]]',
698             # provides => {
699             # 'keys' => 'get_after_method_modifiers',
700             # 'exists' => 'has_after_method_modifiers',
701             # # This actually makes sure there is an
702             # # ARRAY at the given key, and pushed onto
703             # # it. It also checks for duplicates as well
704             # # 'add' => 'add_after_method_modifier'
705             # }
706             # );
707             #
708             # has 'around_method_modifiers' => (
709             # metaclass => 'Hash',
710             # reader =>'get_around_method_modifiers_map',
711             # isa => 'HashRef[ArrayRef[CodeRef]]',
712             # provides => {
713             # 'keys' => 'get_around_method_modifiers',
714             # 'exists' => 'has_around_method_modifiers',
715             # # This actually makes sure there is an
716             # # ARRAY at the given key, and pushed onto
717             # # it. It also checks for duplicates as well
718             # # 'add' => 'add_around_method_modifier'
719             # }
720             # );
721             #
722             # # override is similar to the other modifiers
723             # # except that it is not an ARRAY of code refs
724             # # but instead just a single name->code mapping
725             #
726             # has 'override_method_modifiers' => (
727             # metaclass => 'Hash',
728             # reader =>'get_override_method_modifiers_map',
729             # isa => 'HashRef[CodeRef]',
730             # provides => {
731             # 'keys' => 'get_override_method_modifier',
732             # 'exists' => 'has_override_method_modifier',
733             # 'add' => 'add_override_method_modifier', # checks for local method ..
734             # }
735             # );
736             #
737             #####################################################################
738              
739              
740             1;
741              
742             # ABSTRACT: The Moose Role metaclass
743              
744             __END__
745              
746             =pod
747              
748             =encoding UTF-8
749              
750             =head1 NAME
751              
752             Moose::Meta::Role - The Moose Role metaclass
753              
754             =head1 VERSION
755              
756             version 2.2206
757              
758             =head1 DESCRIPTION
759              
760             This class is a subclass of L<Class::MOP::Module> that provides
761             additional Moose-specific functionality.
762              
763             Its API looks a lot like L<Moose::Meta::Class>, but internally it
764             implements many things differently. This may change in the future.
765              
766             =head1 INHERITANCE
767              
768             C<Moose::Meta::Role> is a subclass of L<Class::MOP::Module>.
769              
770             =head1 METHODS
771              
772             =head2 Construction
773              
774             =head3 Moose::Meta::Role->initialize($role_name)
775              
776             This method creates a new role object with the provided name.
777              
778             =head3 Moose::Meta::Role->combine( [ $role => { ... } ], [ $role ], ... )
779              
780             This method accepts a list of array references. Each array reference
781             should contain a role name or L<Moose::Meta::Role> object as its first element. The second element is
782             an optional hash reference. The hash reference can contain C<-excludes>
783             and C<-alias> keys to control how methods are composed from the role.
784              
785             The return value is a new L<Moose::Meta::Role::Composite> that
786             represents the combined roles.
787              
788             =head3 $metarole->composition_class_roles
789              
790             When combining multiple roles using C<combine>, this method is used to obtain a
791             list of role names to be applied to the L<Moose::Meta::Role::Composite>
792             instance returned by C<combine>. The default implementation returns an empty
793             list. Extensions that need to hook into role combination may wrap this method
794             to return additional role names.
795              
796             =head3 Moose::Meta::Role->create($name, %options)
797              
798             This method is identical to the L<Moose::Meta::Class> C<create>
799             method.
800              
801             =head3 Moose::Meta::Role->create_anon_role
802              
803             This method is identical to the L<Moose::Meta::Class>
804             C<create_anon_class> method.
805              
806             =head3 $metarole->is_anon_role
807              
808             Returns true if the role is an anonymous role.
809              
810             =head3 $metarole->consumers
811              
812             Returns a list of names of classes and roles which consume this role.
813              
814             =head2 Role application
815              
816             =head3 $metarole->apply( $thing, @options )
817              
818             This method applies a role to the given C<$thing>. That can be another
819             L<Moose::Meta::Role>, object, a L<Moose::Meta::Class> object, or a
820             (non-meta) object instance.
821              
822             The options are passed directly to the constructor for the appropriate
823             L<Moose::Meta::Role::Application> subclass.
824              
825             Note that this will apply the role even if the C<$thing> in question already
826             C<does> this role. L<Moose::Util/does_role> is a convenient wrapper for
827             finding out if role application is necessary.
828              
829             =head2 Roles and other roles
830              
831             =head3 $metarole->get_roles
832              
833             This returns an array reference of roles which this role does. This
834             list may include duplicates.
835              
836             =head3 $metarole->calculate_all_roles
837              
838             This returns a I<unique> list of all roles that this role does, and
839             all the roles that its roles do.
840              
841             =head3 $metarole->does_role($role)
842              
843             Given a role I<name> or L<Moose::Meta::Role> object, returns true if this role
844             does the given role.
845              
846             =head3 $metarole->add_role($role)
847              
848             Given a L<Moose::Meta::Role> object, this adds the role to the list of
849             roles that the role does.
850              
851             =head3 $metarole->get_excluded_roles_list
852              
853             Returns a list of role names which this role excludes.
854              
855             =head3 $metarole->excludes_role($role_name)
856              
857             Given a role I<name>, returns true if this role excludes the named
858             role.
859              
860             =head3 $metarole->add_excluded_roles(@role_names)
861              
862             Given one or more role names, adds those roles to the list of excluded
863             roles.
864              
865             =head2 Methods
866              
867             The methods for dealing with a role's methods are all identical in API
868             and behavior to the same methods in L<Class::MOP::Class>.
869              
870             =head3 $metarole->method_metaclass
871              
872             Returns the method metaclass name for the role. This defaults to
873             L<Moose::Meta::Role::Method>.
874              
875             =head3 $metarole->get_method($name)
876              
877             =head3 $metarole->has_method($name)
878              
879             =head3 $metarole->add_method( $name, $body )
880              
881             =head3 $metarole->get_method_list
882              
883             =head3 $metarole->find_method_by_name($name)
884              
885             These methods are all identical to the methods of the same name in
886             L<Class::MOP::Class>
887              
888             =head2 Attributes
889              
890             As with methods, the methods for dealing with a role's attribute are
891             all identical in API and behavior to the same methods in
892             L<Class::MOP::Class>.
893              
894             However, attributes stored in this class are I<not> stored as
895             objects. Rather, the attribute definition is stored as a hash
896             reference. When a role is composed into a class, this hash reference
897             is passed directly to the metaclass's C<add_attribute> method.
898              
899             This is quite likely to change in the future.
900              
901             =head3 $metarole->get_attribute($attribute_name)
902              
903             =head3 $metarole->has_attribute($attribute_name)
904              
905             =head3 $metarole->get_attribute_list
906              
907             =head3 $metarole->add_attribute($name, %options)
908              
909             =head3 $metarole->remove_attribute($attribute_name)
910              
911             =head2 Overload introspection and creation
912              
913             The methods for dealing with a role's overloads are all identical in API and
914             behavior to the same methods in L<Class::MOP::Class>.
915              
916             =head3 $metarole->is_overloaded
917              
918             =head3 $metarole->get_overloaded_operator($op)
919              
920             =head3 $metarole->has_overloaded_operator($op)
921              
922             =head3 $metarole->get_overload_list
923              
924             =head3 $metarole->get_all_overloaded_operators
925              
926             =head3 $metarole->add_overloaded_operator($op, $impl)
927              
928             =head3 $metarole->remove_overloaded_operator($op)
929              
930             =head2 Required methods
931              
932             =head3 $metarole->get_required_method_list
933              
934             Returns the list of methods required by the role.
935              
936             =head3 $metarole->requires_method($name)
937              
938             Returns true if the role requires the named method.
939              
940             =head3 $metarole->add_required_methods(@names)
941              
942             Adds the named methods to the role's list of required methods.
943              
944             =head3 $metarole->remove_required_methods(@names)
945              
946             Removes the named methods from the role's list of required methods.
947              
948             =head3 $metarole->add_conflicting_method(%params)
949              
950             Instantiate the parameters as a L<Moose::Meta::Role::Method::Conflicting>
951             object, then add it to the required method list.
952              
953             =head2 Method modifiers
954              
955             These methods act like their counterparts in L<Class::MOP::Class> and
956             L<Moose::Meta::Class>.
957              
958             However, method modifiers are simply stored internally, and are not applied
959             until the role itself is applied to a class or object.
960              
961             =head3 $metarole->add_after_method_modifier($method_name, $method)
962              
963             =head3 $metarole->add_around_method_modifier($method_name, $method)
964              
965             =head3 $metarole->add_before_method_modifier($method_name, $method)
966              
967             =head3 $metarole->add_override_method_modifier($method_name, $method)
968              
969             These methods all add an appropriate modifier to the internal list of
970             modifiers.
971              
972             =head3 $metarole->has_after_method_modifiers
973              
974             =head3 $metarole->has_around_method_modifiers
975              
976             =head3 $metarole->has_before_method_modifiers
977              
978             =head3 $metarole->has_override_method_modifier
979              
980             Return true if the role has any modifiers of the given type.
981              
982             =head3 $metarole->get_after_method_modifiers($method_name)
983              
984             =head3 $metarole->get_around_method_modifiers($method_name)
985              
986             =head3 $metarole->get_before_method_modifiers($method_name)
987              
988             Given a method name, returns a list of the appropriate modifiers for
989             that method.
990              
991             =head3 $metarole->get_override_method_modifier($method_name)
992              
993             Given a method name, returns the override method modifier for that
994             method, if it has one.
995              
996             =head2 Introspection
997              
998             =head3 Moose::Meta::Role->meta
999              
1000             This will return a L<Class::MOP::Class> instance for this class.
1001              
1002             =head1 BUGS
1003              
1004             See L<Moose/BUGS> for details on reporting bugs.
1005              
1006             =head1 AUTHORS
1007              
1008             =over 4
1009              
1010             =item *
1011              
1012             Stevan Little <stevan@cpan.org>
1013              
1014             =item *
1015              
1016             Dave Rolsky <autarch@urth.org>
1017              
1018             =item *
1019              
1020             Jesse Luehrs <doy@cpan.org>
1021              
1022             =item *
1023              
1024             Shawn M Moore <sartak@cpan.org>
1025              
1026             =item *
1027              
1028             יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
1029              
1030             =item *
1031              
1032             Karen Etheridge <ether@cpan.org>
1033              
1034             =item *
1035              
1036             Florian Ragwitz <rafl@debian.org>
1037              
1038             =item *
1039              
1040             Hans Dieter Pearcey <hdp@cpan.org>
1041              
1042             =item *
1043              
1044             Chris Prather <chris@prather.org>
1045              
1046             =item *
1047              
1048             Matt S Trout <mstrout@cpan.org>
1049              
1050             =back
1051              
1052             =head1 COPYRIGHT AND LICENSE
1053              
1054             This software is copyright (c) 2006 by Infinity Interactive, Inc.
1055              
1056             This is free software; you can redistribute it and/or modify it under
1057             the same terms as the Perl 5 programming language system itself.
1058              
1059             =cut