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.2205';
3              
4 378     378   153071 use strict;
  378         1026  
  378         12394  
5 378     378   2146 use warnings;
  378         983  
  378         9905  
6 378     378   3020 use metaclass;
  378         926  
  378         2350  
7              
8 378     378   3048 use Scalar::Util 'blessed';
  378         1034  
  378         23853  
9              
10 378     378   8054 use Moose::Meta::Class;
  378         1291  
  378         11546  
11 378     378   188829 use Moose::Meta::Role::Attribute;
  378         1424  
  378         15476  
12 378     378   181277 use Moose::Meta::Role::Method;
  378         1161  
  378         14190  
13 378     378   178614 use Moose::Meta::Role::Method::Required;
  378         1215  
  378         13123  
14 378     378   183617 use Moose::Meta::Role::Method::Conflicting;
  378         1241  
  378         15486  
15 378     378   3283 use Moose::Meta::Method::Meta;
  378         1032  
  378         10475  
16 378     378   2169 use Moose::Util qw/throw_exception/;
  378         1029  
  378         2071  
17 378     378   95516 use Class::MOP::MiniTrait;
  378         1089  
  378         13225  
18              
19 378         2048 use parent 'Class::MOP::Module',
20             'Class::MOP::Mixin::HasAttributes',
21             'Class::MOP::Mixin::HasMethods',
22 378     378   2228 'Class::MOP::Mixin::HasOverloads';
  378         1017  
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   912 my ($self, @values) = @_;
91 258         1539 $self->$attr_reader->{$_} = undef foreach @values;
92             }) if exists $methods->{add};
93              
94             $META->add_method($methods->{get_keys} => sub {
95 2199     2199   5588 my ($self) = @_;
96 2199         3733 keys %{$self->$attr_reader};
  2199         74493  
97             }) if exists $methods->{get_keys};
98              
99             $META->add_method($methods->{get_values} => sub {
100 2197     2197   6992 my ($self) = @_;
101 2197         3516 values %{$self->$attr_reader};
  2197         73535  
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   2851 my ($self, $name) = @_;
        652      
111 652 100       22726 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 4736 my $class = shift;
172 1326         3792 my @args = @_;
173 1326 50       6509 unshift @args, 'package' if @args % 2;
174 1326         5337 my %opts = @args;
175 1326         4845 my $package = delete $opts{package};
176 1326   33     5044 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 900 my $self = shift;
185 19         55 my $pkg = shift;
186              
187 19 100       97 my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg);
188              
189 19         51 my %existing_classes;
190 19 50       65 if ($meta) {
191 19         59 %existing_classes = map { $_ => $meta->$_() } qw(
  171         4260  
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         129 my %options = @_;
205             $options{weaken} = Class::MOP::metaclass_is_weak($meta->name)
206             if !exists $options{weaken}
207 19 50 33     278 && 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         196 my $new_meta = $self->SUPER::reinitialize(
214             $pkg,
215             %existing_classes,
216             %options,
217             );
218 19 50 33     353 $new_meta->_restore_metaobjects_from($meta)
219             if $meta && $meta->isa('Moose::Meta::Role');
220 19         164 return $new_meta;
221             }
222              
223             sub _restore_metaobjects_from {
224 19     19   56 my $self = shift;
225 19         53 my ($old_meta) = @_;
226              
227 19         136 $self->_restore_metamethods_from($old_meta);
228 19         135 $self->_restore_metaattributes_from($old_meta);
229              
230 19         50 for my $role ( @{ $old_meta->get_roles } ) {
  19         676  
231 2         9 $self->add_role($role);
232             }
233             }
234              
235             sub add_attribute {
236 732     732 1 1912 my $self = shift;
237              
238 732 100 100     10263 if (blessed $_[0] && ! $_[0]->isa('Moose::Meta::Role::Attribute') ) {
    100 100        
      100        
239 1         5 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         17 throw_exception( AttributeExtensionIsNotSupportedInRoles => attribute_name => $_[0],
246             role_name => $self->name,
247             );
248             }
249              
250 729         5387 return $self->SUPER::add_attribute(@_);
251             }
252              
253             sub _attach_attribute {
254 727     727   1939 my ( $self, $attribute ) = @_;
255              
256 727         2885 $attribute->attach_to_role($self);
257             }
258              
259             sub add_required_methods {
260 692     692 1 1557 my $self = shift;
261              
262 692         2371 for (@_) {
263 577         1032 my $method = $_;
264 577 100       2555 if (!blessed($method)) {
265 185         6853 $method = $self->required_method_metaclass->new(
266             name => $method,
267             );
268             }
269 577         20072 $self->get_required_methods_map->{$method->name} = $method;
270             }
271             }
272              
273             sub add_conflicting_method {
274 135     135 1 286 my $self = shift;
275              
276 135         202 my $method;
277 135 50 33     549 if (@_ == 1 && blessed($_[0])) {
278 0         0 $method = shift;
279             }
280             else {
281 135         4525 $method = $self->conflicting_method_metaclass->new(@_);
282             }
283              
284 135         483 $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   5506 my ($self, $method_name) = @_;
        2314      
        2314      
312             #return () unless exists $self->$attr_reader->{$method_name};
313 2314         82319 my $mm = $self->$attr_reader->{$method_name};
314 2314 100       15169 $mm ? @$mm : ();
315             });
316              
317             $META->add_method("has_${modifier_type}_method_modifiers" => sub {
318 11     11   1986 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       360 (exists $self->$attr_reader->{$method_name}) ? 1 : 0;
323             });
324              
325             $META->add_method("add_${modifier_type}_method_modifier" => sub {
326 1612     1612   3836 my ($self, $method_name, $method) = @_;
        1612      
        1612      
327              
328             $self->$attr_reader->{$method_name} = []
329 1612 100       56216 unless exists $self->$attr_reader->{$method_name};
330              
331 1612         55618 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         2820 foreach my $modifier (@{$modifiers}) {
  1612         3511  
338 17 100       215 return if $modifier == $method;
339             }
340              
341 1597         2288 push @{$modifiers} => $method;
  1597         6471  
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 3214 my ($self, $method_name, $method) = @_;
363 1453 100       4279 (!$self->has_method($method_name))
364             || throw_exception( CannotOverrideALocalMethod => method_name => $method_name,
365             role_name => $self->name,
366             );
367 1451         51509 $self->get_override_method_modifiers_map->{$method_name} = $method;
368             }
369              
370             sub has_override_method_modifier {
371 1051     1051 1 2640 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       37462 (exists $self->get_override_method_modifiers_map->{$method_name}) ? 1 : 0;
376             }
377              
378             sub get_override_method_modifier {
379 2301     2301 1 4442 my ($self, $method_name) = @_;
380 2301         82755 $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 19127 my ($self, $modifier_type) = @_;
387 8426         16493 my $accessor = "get_${modifier_type}_method_modifiers_map";
388 8426         11315 keys %{$self->$accessor};
  8426         308611  
389             }
390              
391 1324     1324   10182 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 1661 my ($self, $role) = @_;
404 501 100 66     4864 (blessed($role) && $role->isa('Moose::Meta::Role'))
405             || throw_exception( AddRoleToARoleTakesAMooseMetaRole => role_to_be_added => $role,
406             role_name => $self->name,
407             );
408 500         1281 push @{$self->get_roles} => $role;
  500         18287  
409 500         2767 $self->reset_package_cache_flag;
410             }
411              
412             sub calculate_all_roles {
413 541     541 1 1022 my $self = shift;
414 541         933 my %seen;
415             grep {
416 756         5202 !$seen{$_->name}++
417             } ($self, map {
418 206         939 $_->calculate_all_roles
419 541         879 } @{ $self->get_roles });
  541         15327  
420             }
421              
422             sub does_role {
423 771     771 1 3593 my ($self, $role) = @_;
424 771 100       1700 (defined $role)
425             || throw_exception( RoleNameRequiredForMooseMetaRole => role_name => $self->name );
426 770 100       2126 my $role_name = blessed $role ? $role->name : $role;
427             # if we are it,.. then return true
428 770 100       10949 return 1 if $role_name eq $self->name;
429             # otherwise.. check our children
430 385         621 foreach my $role (@{$self->get_roles}) {
  385         10709  
431 271 100       697 return 1 if $role->does_role($role_name);
432             }
433 223         738 return 0;
434             }
435              
436 1962     1962 1 6816 sub find_method_by_name { (shift)->get_method(@_) }
437              
438             ## ------------------------------------------------------------------
439             ## role construction
440             ## ------------------------------------------------------------------
441              
442             sub apply {
443 1646     1646 1 4815 my ($self, $other, %args) = @_;
444              
445 1646 100       7055 (blessed($other))
446             || throw_exception( ApplyTakesABlessedInstance => param => $other,
447             role_name => $self->name,
448             );
449              
450 1645         3276 my $application_class;
451 1645 100       11883 if ($other->isa('Moose::Meta::Role')) {
    100          
452 505         18454 $application_class = $self->application_to_role_class;
453             }
454             elsif ($other->isa('Moose::Meta::Class')) {
455 1117         41531 $application_class = $self->application_to_class_class;
456             }
457             else {
458 23         848 $application_class = $self->application_to_instance_class;
459             }
460              
461 1645         6444 Moose::Util::_load_user_class($application_class);
462              
463 1645 100       98092 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       71 : [ $args{'-excludes'} ]
469             );
470             }
471              
472 1645         18183 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 996 my ($class, @role_specs) = @_;
479              
480 231         1575 require Moose::Meta::Role::Composite;
481              
482 231         632 my (@roles, %role_params);
483 231         919 while (@role_specs) {
484 519         930 my ($role, $params) = @{ splice @role_specs, 0, 1 };
  519         1337  
485 519 100       1900 my $requested_role
486             = blessed $role
487             ? $role
488             : Class::MOP::class_of($role);
489              
490 519         1572 my $actual_role = $requested_role->_role_for_combination($params);
491 519         999 push @roles => $actual_role;
492              
493 519 100       1795 next unless defined $params;
494 29         155 $role_params{$actual_role->name} = $params;
495             }
496              
497 231         2698 my $c = Moose::Meta::Role::Composite->new(roles => \@roles);
498 231         1613 return $c->apply_params(\%role_params);
499             }
500              
501             sub _role_for_combination {
502 518     518   1059 my ($self, $params) = @_;
503 518         955 return $self;
504             }
505              
506             sub create {
507 16     16 1 458 my $class = shift;
508 16         55 my @args = @_;
509              
510 16 50       89 unshift @args, 'package' if @args % 2 == 1;
511 16         70 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     82 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     83 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     52 if exists $options{roles};
530              
531 13         35 my $package = delete $options{package};
532 13         30 my $roles = delete $options{roles};
533 13         26 my $attributes = delete $options{attributes};
534 13         30 my $methods = delete $options{methods};
535             my $meta_name = exists $options{meta_name}
536             ? delete $options{meta_name}
537 13 50       55 : 'meta';
538              
539 13         167 my $meta = $class->SUPER::create($package => %options);
540              
541 13 50       111 $meta->_add_meta_method($meta_name)
542             if defined $meta_name;
543              
544 13 100       56 if (defined $attributes) {
545 2         6 foreach my $attribute_name (keys %{$attributes}) {
  2         10  
546 2         6 my $attr = $attributes->{$attribute_name};
547             $meta->add_attribute(
548 2 50       14 $attribute_name => blessed $attr ? $attr : %{$attr} );
  2         13  
549             }
550             }
551              
552 13 100       46 if (defined $methods) {
553 7         17 foreach my $method_name (keys %{$methods}) {
  7         27  
554 7         31 $meta->add_method($method_name, $methods->{$method_name});
555             }
556             }
557              
558 13 100       49 if ($roles) {
559 1         5 Moose::Util::apply_all_roles($meta, @$roles);
560             }
561              
562 13         65 return $meta;
563             }
564              
565             sub consumers {
566 3     3 1 5 my $self = shift;
567 3         5 my @consumers;
568 3         8 for my $meta (Class::MOP::get_all_metaclass_instances) {
569 225 100       509 next if $meta->name eq $self->name;
570 222 100 100     726 next unless $meta->isa('Moose::Meta::Class')
571             || $meta->isa('Moose::Meta::Role');
572 21 100       50 push @consumers, $meta->name
573             if $meta->does_role($self->name);
574             }
575 3         38 return @consumers;
576             }
577              
578             # XXX: something more intelligent here?
579 49     49   163 sub _anon_package_prefix { 'Moose::Meta::Role::__ANON__::SERIAL::' }
580              
581 11     11 1 3258 sub create_anon_role { shift->create_anon(@_) }
582 2     2 1 4252 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.2205
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