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.2203';
3              
4 389     389   183635 use strict;
  389         802  
  389         11218  
5 389     389   1857 use warnings;
  389         746  
  389         8693  
6 389     389   2407 use metaclass;
  389         754  
  389         1945  
7              
8 389     389   2738 use Scalar::Util 'blessed';
  389         908  
  389         21218  
9              
10 389     389   7024 use Moose::Meta::Class;
  389         891  
  389         10841  
11 389     389   163971 use Moose::Meta::Role::Attribute;
  389         1111  
  389         14183  
12 389     389   159841 use Moose::Meta::Role::Method;
  389         982  
  389         12661  
13 389     389   156928 use Moose::Meta::Role::Method::Required;
  389         1000  
  389         11673  
14 389     389   161279 use Moose::Meta::Role::Method::Conflicting;
  389         1028  
  389         12102  
15 389     389   2655 use Moose::Meta::Method::Meta;
  389         778  
  389         9266  
16 389     389   1845 use Moose::Util qw/throw_exception/;
  389         751  
  389         1626  
17 389     389   86003 use Class::MOP::MiniTrait;
  389         814  
  389         11761  
18              
19 389         1734 use parent 'Class::MOP::Module',
20             'Class::MOP::Mixin::HasAttributes',
21             'Class::MOP::Mixin::HasMethods',
22 389     389   1867 'Class::MOP::Mixin::HasOverloads';
  389         788  
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   794 my ($self, @values) = @_;
91 258         1311 $self->$attr_reader->{$_} = undef foreach @values;
92             }) if exists $methods->{add};
93              
94             $META->add_method($methods->{get_keys} => sub {
95 2208     2208   5050 my ($self) = @_;
96 2208         3210 keys %{$self->$attr_reader};
  2208         65498  
97             }) if exists $methods->{get_keys};
98              
99             $META->add_method($methods->{get_values} => sub {
100 2206     2206   6548 my ($self) = @_;
101 2206         3058 values %{$self->$attr_reader};
  2206         65728  
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   2749 my ($self, $name) = @_;
        652      
111 652 100       20111 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 1332     1332 1 4279 my $class = shift;
172 1332         3292 my @args = @_;
173 1332 50       5823 unshift @args, 'package' if @args % 2;
174 1332         4778 my %opts = @args;
175 1332         4247 my $package = delete $opts{package};
176 1332   33     4408 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 721 my $self = shift;
185 19         35 my $pkg = shift;
186              
187 19 100       81 my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg);
188              
189 19         38 my %existing_classes;
190 19 50       71 if ($meta) {
191 19         54 %existing_classes = map { $_ => $meta->$_() } qw(
  171         3619  
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         102 my %options = @_;
205             $options{weaken} = Class::MOP::metaclass_is_weak($meta->name)
206             if !exists $options{weaken}
207 19 50 33     236 && 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         159 my $new_meta = $self->SUPER::reinitialize(
214             $pkg,
215             %existing_classes,
216             %options,
217             );
218 19 50 33     232 $new_meta->_restore_metaobjects_from($meta)
219             if $meta && $meta->isa('Moose::Meta::Role');
220 19         135 return $new_meta;
221             }
222              
223             sub _restore_metaobjects_from {
224 19     19   47 my $self = shift;
225 19         47 my ($old_meta) = @_;
226              
227 19         111 $self->_restore_metamethods_from($old_meta);
228 19         106 $self->_restore_metaattributes_from($old_meta);
229              
230 19         41 for my $role ( @{ $old_meta->get_roles } ) {
  19         586  
231 2         6 $self->add_role($role);
232             }
233             }
234              
235             sub add_attribute {
236 733     733 1 1615 my $self = shift;
237              
238 733 100 100     8582 if (blessed $_[0] && ! $_[0]->isa('Moose::Meta::Role::Attribute') ) {
    100 100        
      100        
239 1         2 my $class = ref $_[0];
240 1         11 throw_exception( CannotAddAsAnAttributeToARole => role_name => $self->name,
241             attribute_class => $class,
242             );
243             }
244             elsif (!blessed($_[0]) && defined($_[0]) && $_[0] =~ /^\+(.*)/) {
245 2         18 throw_exception( AttributeExtensionIsNotSupportedInRoles => attribute_name => $_[0],
246             role_name => $self->name,
247             );
248             }
249              
250 730         4758 return $self->SUPER::add_attribute(@_);
251             }
252              
253             sub _attach_attribute {
254 728     728   1637 my ( $self, $attribute ) = @_;
255              
256 728         2408 $attribute->attach_to_role($self);
257             }
258              
259             sub add_required_methods {
260 692     692 1 1407 my $self = shift;
261              
262 692         2191 for (@_) {
263 577         939 my $method = $_;
264 577 100       2015 if (!blessed($method)) {
265 185         5950 $method = $self->required_method_metaclass->new(
266             name => $method,
267             );
268             }
269 577         17869 $self->get_required_methods_map->{$method->name} = $method;
270             }
271             }
272              
273             sub add_conflicting_method {
274 135     135 1 573 my $self = shift;
275              
276 135         212 my $method;
277 135 50 33     479 if (@_ == 1 && blessed($_[0])) {
278 0         0 $method = shift;
279             }
280             else {
281 135         4070 $method = $self->conflicting_method_metaclass->new(@_);
282             }
283              
284 135         407 $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 2321     2321   5198 my ($self, $method_name) = @_;
        2321      
        2321      
312             #return () unless exists $self->$attr_reader->{$method_name};
313 2321         72412 my $mm = $self->$attr_reader->{$method_name};
314 2321 100       12763 $mm ? @$mm : ();
315             });
316              
317             $META->add_method("has_${modifier_type}_method_modifiers" => sub {
318 11     11   2039 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       385 (exists $self->$attr_reader->{$method_name}) ? 1 : 0;
323             });
324              
325             $META->add_method("add_${modifier_type}_method_modifier" => sub {
326 1616     1616   3362 my ($self, $method_name, $method) = @_;
        1616      
        1616      
327              
328             $self->$attr_reader->{$method_name} = []
329 1616 100       49085 unless exists $self->$attr_reader->{$method_name};
330              
331 1616         46671 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 1616         2728 foreach my $modifier (@{$modifiers}) {
  1616         3042  
338 17 100       145 return if $modifier == $method;
339             }
340              
341 1601         2049 push @{$modifiers} => $method;
  1601         5649  
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 2813 my ($self, $method_name, $method) = @_;
363 1453 100       3760 (!$self->has_method($method_name))
364             || throw_exception( CannotOverrideALocalMethod => method_name => $method_name,
365             role_name => $self->name,
366             );
367 1451         45401 $self->get_override_method_modifiers_map->{$method_name} = $method;
368             }
369              
370             sub has_override_method_modifier {
371 1051     1051 1 2439 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       32967 (exists $self->get_override_method_modifiers_map->{$method_name}) ? 1 : 0;
376             }
377              
378             sub get_override_method_modifier {
379 2301     2301 1 4075 my ($self, $method_name) = @_;
380 2301         73250 $self->get_override_method_modifiers_map->{$method_name};
381             }
382              
383             ## general list accessor ...
384              
385             sub get_method_modifier_list {
386 8462     8462 0 17109 my ($self, $modifier_type) = @_;
387 8462         14827 my $accessor = "get_${modifier_type}_method_modifiers_map";
388 8462         10571 keys %{$self->$accessor};
  8462         270317  
389             }
390              
391 1330     1330   9123 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 1606 my ($self, $role) = @_;
404 501 100 66     4430 (blessed($role) && $role->isa('Moose::Meta::Role'))
405             || throw_exception( AddRoleToARoleTakesAMooseMetaRole => role_to_be_added => $role,
406             role_name => $self->name,
407             );
408 500         1091 push @{$self->get_roles} => $role;
  500         16113  
409 500         2551 $self->reset_package_cache_flag;
410             }
411              
412             sub calculate_all_roles {
413 541     541 1 1212 my $self = shift;
414 541         766 my %seen;
415             grep {
416 756         4053 !$seen{$_->name}++
417             } ($self, map {
418 206         717 $_->calculate_all_roles
419 541         818 } @{ $self->get_roles });
  541         13076  
420             }
421              
422             sub does_role {
423 772     772 1 3806 my ($self, $role) = @_;
424 772 100       1529 (defined $role)
425             || throw_exception( RoleNameRequiredForMooseMetaRole => role_name => $self->name );
426 771 100       1991 my $role_name = blessed $role ? $role->name : $role;
427             # if we are it,.. then return true
428 771 100       9485 return 1 if $role_name eq $self->name;
429             # otherwise.. check our children
430 385         597 foreach my $role (@{$self->get_roles}) {
  385         9745  
431 271 100       674 return 1 if $role->does_role($role_name);
432             }
433 223         666 return 0;
434             }
435              
436 1968     1968 1 5884 sub find_method_by_name { (shift)->get_method(@_) }
437              
438             ## ------------------------------------------------------------------
439             ## role construction
440             ## ------------------------------------------------------------------
441              
442             sub apply {
443 1655     1655 1 3967 my ($self, $other, %args) = @_;
444              
445 1655 100       6664 (blessed($other))
446             || throw_exception( ApplyTakesABlessedInstance => param => $other,
447             role_name => $self->name,
448             );
449              
450 1654         3045 my $application_class;
451 1654 100       10029 if ($other->isa('Moose::Meta::Role')) {
    100          
452 505         16636 $application_class = $self->application_to_role_class;
453             }
454             elsif ($other->isa('Moose::Meta::Class')) {
455 1126         36483 $application_class = $self->application_to_class_class;
456             }
457             else {
458 23         787 $application_class = $self->application_to_instance_class;
459             }
460              
461 1654         5726 Moose::Util::_load_user_class($application_class);
462              
463 1654 100       85917 if ( exists $args{'-excludes'} ) {
464             # I wish we had coercion here :)
465             $args{'-excludes'} = (
466             ref $args{'-excludes'} eq 'ARRAY'
467             ? $args{'-excludes'}
468 13 100       67 : [ $args{'-excludes'} ]
469             );
470             }
471              
472 1654         15545 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 799 my ($class, @role_specs) = @_;
479              
480 231         1381 require Moose::Meta::Role::Composite;
481              
482 231         535 my (@roles, %role_params);
483 231         746 while (@role_specs) {
484 519         821 my ($role, $params) = @{ splice @role_specs, 0, 1 };
  519         1183  
485 519 100       1705 my $requested_role
486             = blessed $role
487             ? $role
488             : Class::MOP::class_of($role);
489              
490 519         1370 my $actual_role = $requested_role->_role_for_combination($params);
491 519         881 push @roles => $actual_role;
492              
493 519 100       1560 next unless defined $params;
494 29         147 $role_params{$actual_role->name} = $params;
495             }
496              
497 231         1979 my $c = Moose::Meta::Role::Composite->new(roles => \@roles);
498 231         1282 return $c->apply_params(\%role_params);
499             }
500              
501             sub _role_for_combination {
502 518     518   1069 my ($self, $params) = @_;
503 518         825 return $self;
504             }
505              
506             sub create {
507 16     16 1 400 my $class = shift;
508 16         48 my @args = @_;
509              
510 16 50       117 unshift @args, 'package' if @args % 2 == 1;
511 16         99 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     62 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     75 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     50 if exists $options{roles};
530              
531 13         32 my $package = delete $options{package};
532 13         30 my $roles = delete $options{roles};
533 13         25 my $attributes = delete $options{attributes};
534 13         26 my $methods = delete $options{methods};
535             my $meta_name = exists $options{meta_name}
536             ? delete $options{meta_name}
537 13 50       40 : 'meta';
538              
539 13         84 my $meta = $class->SUPER::create($package => %options);
540              
541 13 50       97 $meta->_add_meta_method($meta_name)
542             if defined $meta_name;
543              
544 13 100       50 if (defined $attributes) {
545 2         4 foreach my $attribute_name (keys %{$attributes}) {
  2         7  
546 2         4 my $attr = $attributes->{$attribute_name};
547             $meta->add_attribute(
548 2 50       11 $attribute_name => blessed $attr ? $attr : %{$attr} );
  2         11  
549             }
550             }
551              
552 13 100       41 if (defined $methods) {
553 7         20 foreach my $method_name (keys %{$methods}) {
  7         24  
554 7         29 $meta->add_method($method_name, $methods->{$method_name});
555             }
556             }
557              
558 13 100       42 if ($roles) {
559 1         4 Moose::Util::apply_all_roles($meta, @$roles);
560             }
561              
562 13         59 return $meta;
563             }
564              
565             sub consumers {
566 3     3 1 7 my $self = shift;
567 3         6 my @consumers;
568 3         8 for my $meta (Class::MOP::get_all_metaclass_instances) {
569 225 100       794 next if $meta->name eq $self->name;
570 222 100 100     885 next unless $meta->isa('Moose::Meta::Class')
571             || $meta->isa('Moose::Meta::Role');
572 21 100       72 push @consumers, $meta->name
573             if $meta->does_role($self->name);
574             }
575 3         59 return @consumers;
576             }
577              
578             # XXX: something more intelligent here?
579 47     47   136 sub _anon_package_prefix { 'Moose::Meta::Role::__ANON__::SERIAL::' }
580              
581 11     11 1 3718 sub create_anon_role { shift->create_anon(@_) }
582 2     2 1 3038 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.2203
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