eb311611f8db7e8f2aac0a91c39ee000f3d49947
[gitmo/Moose.git] / lib / Moose / Meta / Role.pm
1 package Moose::Meta::Role;
2
3 use strict;
4 use warnings;
5 use metaclass;
6
7 use Class::Load qw(load_class);
8 use Scalar::Util 'blessed';
9 use Devel::GlobalDestruction 'in_global_destruction';
10
11 use Moose::Meta::Class;
12 use Moose::Meta::Role::Attribute;
13 use Moose::Meta::Role::Method;
14 use Moose::Meta::Role::Method::Required;
15 use Moose::Meta::Role::Method::Conflicting;
16 use Moose::Meta::Method::Meta;
17 use Moose::Util qw( ensure_all_roles );
18 use Class::MOP::MiniTrait;
19
20 use base 'Class::MOP::Module',
21          'Class::MOP::Mixin::HasAttributes',
22          'Class::MOP::Mixin::HasMethods';
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 an 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         my ($self, @values) = @_;
91         $self->$attr_reader->{$_} = undef foreach @values;
92     }) if exists $methods->{add};
93
94     $META->add_method($methods->{get_keys} => sub {
95         my ($self) = @_;
96         keys %{$self->$attr_reader};
97     }) if exists $methods->{get_keys};
98
99     $META->add_method($methods->{get_values} => sub {
100         my ($self) = @_;
101         values %{$self->$attr_reader};
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         my ($self, $name) = @_;
111         exists $self->$attr_reader->{$name} ? 1 : 0;
112     }) if exists $methods->{existence};
113
114     $META->add_method($methods->{remove} => sub {
115         my ($self, @values) = @_;
116         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     my $class = shift;
172     my @args = @_;
173     unshift @args, 'package' if @args % 2;
174     my %opts = @args;
175     my $package = delete $opts{package};
176     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     my $self = shift;
185     my $pkg  = shift;
186
187     my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg);
188
189     my %existing_classes;
190     if ($meta) {
191         %existing_classes = map { $_ => $meta->$_() } qw(
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     my %options = @_;
205     $options{weaken} = Class::MOP::metaclass_is_weak($meta->name)
206         if !exists $options{weaken}
207         && blessed($meta)
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     my $new_meta = $self->SUPER::reinitialize(
214         $pkg,
215         %existing_classes,
216         %options,
217     );
218     $new_meta->_restore_metaobjects_from($meta)
219         if $meta && $meta->isa('Moose::Meta::Role');
220     return $new_meta;
221 }
222
223 sub _restore_metaobjects_from {
224     my $self = shift;
225     my ($old_meta) = @_;
226
227     $self->_restore_metamethods_from($old_meta);
228     $self->_restore_metaattributes_from($old_meta);
229
230     for my $role ( @{ $old_meta->get_roles } ) {
231         $self->add_role($role);
232     }
233 }
234
235 sub add_attribute {
236     my $self = shift;
237
238     if (blessed $_[0] && ! $_[0]->isa('Moose::Meta::Role::Attribute') ) {
239         my $class = ref $_[0];
240         Moose::Util::throw( "Cannot add a $class as an attribute to a role" );
241     }
242     elsif (!blessed($_[0]) && defined($_[0]) && $_[0] =~ /^\+(.*)/) {
243         Moose::Util::throw( "has '+attr' is not supported in roles" );
244     }
245
246     return $self->SUPER::add_attribute(@_);
247 }
248
249 sub _attach_attribute {
250     my ( $self, $attribute ) = @_;
251
252     $attribute->attach_to_role($self);
253 }
254
255 sub add_required_methods {
256     my $self = shift;
257
258     for (@_) {
259         my $method = $_;
260         if (!blessed($method)) {
261             $method = $self->required_method_metaclass->new(
262                 name => $method,
263             );
264         }
265         $self->get_required_methods_map->{$method->name} = $method;
266     }
267 }
268
269 sub add_conflicting_method {
270     my $self = shift;
271
272     my $method;
273     if (@_ == 1 && blessed($_[0])) {
274         $method = shift;
275     }
276     else {
277         $method = $self->conflicting_method_metaclass->new(@_);
278     }
279
280     $self->add_required_methods($method);
281 }
282
283 ## ------------------------------------------------------------------
284 ## method modifiers
285
286 # NOTE:
287 # the before/around/after method modifiers are
288 # stored by name, but there can be many methods
289 # then associated with that name. So again we have
290 # lots of similar functionality, so we can do some
291 # meta-programmin' and save some time.
292 # - SL
293
294 foreach my $modifier_type (qw[ before around after ]) {
295
296     my $attr_reader = "get_${modifier_type}_method_modifiers_map";
297
298     # create the attribute ...
299     $META->add_attribute("${modifier_type}_method_modifiers" => (
300         reader  => $attr_reader,
301         default => sub { {} },
302         Class::MOP::_definition_context(),
303     ));
304
305     # and some helper methods ...
306     $META->add_method("get_${modifier_type}_method_modifiers" => sub {
307         my ($self, $method_name) = @_;
308         #return () unless exists $self->$attr_reader->{$method_name};
309         my $mm = $self->$attr_reader->{$method_name};
310         $mm ? @$mm : ();
311     });
312
313     $META->add_method("has_${modifier_type}_method_modifiers" => sub {
314         my ($self, $method_name) = @_;
315         # NOTE:
316         # for now we assume that if it exists,..
317         # it has at least one modifier in it
318         (exists $self->$attr_reader->{$method_name}) ? 1 : 0;
319     });
320
321     $META->add_method("add_${modifier_type}_method_modifier" => sub {
322         my ($self, $method_name, $method) = @_;
323
324         $self->$attr_reader->{$method_name} = []
325             unless exists $self->$attr_reader->{$method_name};
326
327         my $modifiers = $self->$attr_reader->{$method_name};
328
329         # NOTE:
330         # check to see that we aren't adding the
331         # same code twice. We err in favor of the
332         # first on here, this may not be as expected
333         foreach my $modifier (@{$modifiers}) {
334             return if $modifier == $method;
335         }
336
337         push @{$modifiers} => $method;
338     });
339
340 }
341
342 ## ------------------------------------------------------------------
343 ## override method mofidiers
344
345 $META->add_attribute('override_method_modifiers' => (
346     reader  => 'get_override_method_modifiers_map',
347     default => sub { {} },
348     Class::MOP::_definition_context(),
349 ));
350
351 # NOTE:
352 # these are a little different because there
353 # can only be one per name, whereas the other
354 # method modifiers can have multiples.
355 # - SL
356
357 sub add_override_method_modifier {
358     my ($self, $method_name, $method) = @_;
359     (!$self->has_method($method_name))
360         || Moose::Util::throw("Cannot add an override of method '$method_name' " .
361                    "because there is a local version of '$method_name'");
362     $self->get_override_method_modifiers_map->{$method_name} = $method;
363 }
364
365 sub has_override_method_modifier {
366     my ($self, $method_name) = @_;
367     # NOTE:
368     # for now we assume that if it exists,..
369     # it has at least one modifier in it
370     (exists $self->get_override_method_modifiers_map->{$method_name}) ? 1 : 0;
371 }
372
373 sub get_override_method_modifier {
374     my ($self, $method_name) = @_;
375     $self->get_override_method_modifiers_map->{$method_name};
376 }
377
378 ## general list accessor ...
379
380 sub get_method_modifier_list {
381     my ($self, $modifier_type) = @_;
382     my $accessor = "get_${modifier_type}_method_modifiers_map";
383     keys %{$self->$accessor};
384 }
385
386 sub _meta_method_class { 'Moose::Meta::Method::Meta' }
387
388 ## ------------------------------------------------------------------
389 ## subroles
390
391 $META->add_attribute('roles' => (
392     reader  => 'get_roles',
393     default => sub { [] },
394     Class::MOP::_definition_context(),
395 ));
396
397 sub add_role {
398     my ($self, $role) = @_;
399     (blessed($role) && $role->isa('Moose::Meta::Role'))
400         || Moose::Util::throw("Roles must be instances of Moose::Meta::Role");
401     push @{$self->get_roles} => $role;
402     $self->reset_package_cache_flag;
403 }
404
405 sub calculate_all_roles {
406     my $self = shift;
407     my %seen;
408     grep {
409         !$seen{$_->name}++
410     } ($self, map {
411                   $_->calculate_all_roles
412               } @{ $self->get_roles });
413 }
414
415 sub does_role {
416     my ($self, $role) = @_;
417     (defined $role)
418         || Moose::Util::throw("You must supply a role name to look for");
419     my $role_name = blessed $role ? $role->name : $role;
420     # if we are it,.. then return true
421     return 1 if $role_name eq $self->name;
422     # otherwise.. check our children
423     foreach my $role (@{$self->get_roles}) {
424         return 1 if $role->does_role($role_name);
425     }
426     return 0;
427 }
428
429 sub find_method_by_name { (shift)->get_method(@_) }
430
431 ## ------------------------------------------------------------------
432 ## role construction
433 ## ------------------------------------------------------------------
434
435 sub apply {
436     my ($self, $other, %args) = @_;
437
438     (blessed($other))
439         || Moose::Util::throw("You must pass in an blessed instance");
440
441     my $application_class;
442     if ($other->isa('Moose::Meta::Role')) {
443         $application_class = $self->application_to_role_class;
444     }
445     elsif ($other->isa('Moose::Meta::Class')) {
446         $application_class = $self->application_to_class_class;
447     }
448     else {
449         $application_class = $self->application_to_instance_class;
450     }
451
452     load_class($application_class);
453
454     if ( exists $args{'-excludes'} ) {
455         # I wish we had coercion here :)
456         $args{'-excludes'} = (
457             ref $args{'-excludes'} eq 'ARRAY'
458             ? $args{'-excludes'}
459             : [ $args{'-excludes'} ]
460         );
461     }
462
463     return $application_class->new(%args)->apply($self, $other, \%args);
464 }
465
466 sub composition_class_roles { }
467
468 sub combine {
469     my ($class, @role_specs) = @_;
470
471     require Moose::Meta::Role::Composite;
472
473     my (@roles, %role_params);
474     while (@role_specs) {
475         my ($role, $params) = @{ splice @role_specs, 0, 1 };
476         my $requested_role
477             = blessed $role
478             ? $role
479             : Class::MOP::class_of($role);
480
481         my $actual_role = $requested_role->_role_for_combination($params);
482         push @roles => $actual_role;
483
484         next unless defined $params;
485         $role_params{$actual_role->name} = $params;
486     }
487
488     my $c = Moose::Meta::Role::Composite->new(roles => \@roles);
489     return $c->apply_params(\%role_params);
490 }
491
492 sub _role_for_combination {
493     my ($self, $params) = @_;
494     return $self;
495 }
496
497 sub create {
498     my $class = shift;
499     my @args = @_;
500
501     unshift @args, 'package' if @args % 2 == 1;
502     my %options = @args;
503
504     (ref $options{attributes} eq 'HASH')
505         || Moose::Util::throw "You must pass a HASH ref of attributes"
506             if exists $options{attributes};
507
508     (ref $options{methods} eq 'HASH')
509         || Moose::Util::throw "You must pass a HASH ref of methods"
510             if exists $options{methods};
511
512     (ref $options{roles} eq 'ARRAY')
513         || Moose::Util::throw "You must pass an ARRAY ref of roles"
514             if exists $options{roles};
515
516     my $package      = delete $options{package};
517     my $roles        = delete $options{roles};
518     my $attributes   = delete $options{attributes};
519     my $methods      = delete $options{methods};
520     my $meta_name    = exists $options{meta_name}
521                          ? delete $options{meta_name}
522                          : 'meta';
523
524     my $meta = $class->SUPER::create($package => %options);
525
526     $meta->_add_meta_method($meta_name)
527         if defined $meta_name;
528
529     if (defined $attributes) {
530         foreach my $attribute_name (keys %{$attributes}) {
531             my $attr = $attributes->{$attribute_name};
532             $meta->add_attribute(
533                 $attribute_name => blessed $attr ? $attr : %{$attr} );
534         }
535     }
536
537     if (defined $methods) {
538         foreach my $method_name (keys %{$methods}) {
539             $meta->add_method($method_name, $methods->{$method_name});
540         }
541     }
542
543     if ($roles) {
544         Moose::Util::apply_all_roles($meta, @$roles);
545     }
546
547     return $meta;
548 }
549
550 sub consumers {
551     my $self = shift;
552     my @consumers;
553     for my $meta (Class::MOP::get_all_metaclass_instances) {
554         next if $meta->name eq $self->name;
555         next unless $meta->isa('Moose::Meta::Class')
556                  || $meta->isa('Moose::Meta::Role');
557         push @consumers, $meta->name
558             if $meta->does_role($self->name);
559     }
560     return @consumers;
561 }
562
563 # XXX: something more intelligent here?
564 sub _anon_package_prefix { 'Moose::Meta::Role::__ANON__::SERIAL::' }
565
566 sub create_anon_role { shift->create_anon(@_) }
567 sub is_anon_role     { shift->is_anon(@_)     }
568
569 sub _anon_cache_key {
570     my $class = shift;
571     my %options = @_;
572
573     # XXX fix this duplication (see MMC::_anon_cache_key
574     my $roles = Data::OptList::mkopt(($options{roles} || []), {
575         moniker  => 'role',
576         val_test => sub { ref($_[0]) eq 'HASH' },
577     });
578
579     my @role_keys;
580     for my $role_spec (@$roles) {
581         my ($role, $params) = @$role_spec;
582         $params = { %$params };
583
584         my $key = blessed($role) ? $role->name : $role;
585
586         if ($params && %$params) {
587             my $alias    = delete $params->{'-alias'}
588                         || delete $params->{'alias'}
589                         || {};
590             my $excludes = delete $params->{'-excludes'}
591                         || delete $params->{'excludes'}
592                         || [];
593             $excludes = [$excludes] unless ref($excludes) eq 'ARRAY';
594
595             if (%$params) {
596                 warn "Roles with parameters cannot be cached. Consider "
597                    . "applying the parameters before calling "
598                    . "create_anon_class, or using 'weaken => 0' instead";
599                 return;
600             }
601
602             my $alias_key = join('%',
603                 map { $_ => $alias->{$_} } sort keys %$alias
604             );
605             my $excludes_key = join('%',
606                 sort @$excludes
607             );
608             $key .= '<' . join('+', 'a', $alias_key, 'e', $excludes_key) . '>';
609         }
610
611         push @role_keys, $key;
612     }
613
614     # Makes something like Role|Role::1
615     return join('|', sort @role_keys);
616 }
617
618 #####################################################################
619 ## NOTE:
620 ## This is Moose::Meta::Role as defined by Moose (plus the use of
621 ## MooseX::AttributeHelpers module). It is here as a reference to
622 ## make it easier to see what is happening above with all the meta
623 ## programming. - SL
624 #####################################################################
625 #
626 # has 'roles' => (
627 #     metaclass => 'Array',
628 #     reader    => 'get_roles',
629 #     isa       => 'ArrayRef[Moose::Meta::Role]',
630 #     default   => sub { [] },
631 #     provides  => {
632 #         'push' => 'add_role',
633 #     }
634 # );
635 #
636 # has 'excluded_roles_map' => (
637 #     metaclass => 'Hash',
638 #     reader    => 'get_excluded_roles_map',
639 #     isa       => 'HashRef[Str]',
640 #     provides  => {
641 #         # Not exactly set, cause it sets multiple
642 #         'set'    => 'add_excluded_roles',
643 #         'keys'   => 'get_excluded_roles_list',
644 #         'exists' => 'excludes_role',
645 #     }
646 # );
647 #
648 # has 'required_methods' => (
649 #     metaclass => 'Hash',
650 #     reader    => 'get_required_methods_map',
651 #     isa       => 'HashRef[Moose::Meta::Role::Method::Required]',
652 #     provides  => {
653 #         # not exactly set, or delete since it works for multiple
654 #         'set'    => 'add_required_methods',
655 #         'delete' => 'remove_required_methods',
656 #         'keys'   => 'get_required_method_list',
657 #         'exists' => 'requires_method',
658 #     }
659 # );
660 #
661 # # the before, around and after modifiers are
662 # # HASH keyed by method-name, with ARRAY of
663 # # CODE refs to apply in that order
664 #
665 # has 'before_method_modifiers' => (
666 #     metaclass => 'Hash',
667 #     reader    => 'get_before_method_modifiers_map',
668 #     isa       => 'HashRef[ArrayRef[CodeRef]]',
669 #     provides  => {
670 #         'keys'   => 'get_before_method_modifiers',
671 #         'exists' => 'has_before_method_modifiers',
672 #         # This actually makes sure there is an
673 #         # ARRAY at the given key, and pushed onto
674 #         # it. It also checks for duplicates as well
675 #         # 'add'  => 'add_before_method_modifier'
676 #     }
677 # );
678 #
679 # has 'after_method_modifiers' => (
680 #     metaclass => 'Hash',
681 #     reader    =>'get_after_method_modifiers_map',
682 #     isa       => 'HashRef[ArrayRef[CodeRef]]',
683 #     provides  => {
684 #         'keys'   => 'get_after_method_modifiers',
685 #         'exists' => 'has_after_method_modifiers',
686 #         # This actually makes sure there is an
687 #         # ARRAY at the given key, and pushed onto
688 #         # it. It also checks for duplicates as well
689 #         # 'add'  => 'add_after_method_modifier'
690 #     }
691 # );
692 #
693 # has 'around_method_modifiers' => (
694 #     metaclass => 'Hash',
695 #     reader    =>'get_around_method_modifiers_map',
696 #     isa       => 'HashRef[ArrayRef[CodeRef]]',
697 #     provides  => {
698 #         'keys'   => 'get_around_method_modifiers',
699 #         'exists' => 'has_around_method_modifiers',
700 #         # This actually makes sure there is an
701 #         # ARRAY at the given key, and pushed onto
702 #         # it. It also checks for duplicates as well
703 #         # 'add'  => 'add_around_method_modifier'
704 #     }
705 # );
706 #
707 # # override is similar to the other modifiers
708 # # except that it is not an ARRAY of code refs
709 # # but instead just a single name->code mapping
710 #
711 # has 'override_method_modifiers' => (
712 #     metaclass => 'Hash',
713 #     reader    =>'get_override_method_modifiers_map',
714 #     isa       => 'HashRef[CodeRef]',
715 #     provides  => {
716 #         'keys'   => 'get_override_method_modifier',
717 #         'exists' => 'has_override_method_modifier',
718 #         'add'    => 'add_override_method_modifier', # checks for local method ..
719 #     }
720 # );
721 #
722 #####################################################################
723
724
725 1;
726
727 # ABSTRACT: The Moose Role metaclass
728
729 __END__
730
731 =pod
732
733 =head1 DESCRIPTION
734
735 This class is a subclass of L<Class::MOP::Module> that provides
736 additional Moose-specific functionality.
737
738 Its API looks a lot like L<Moose::Meta::Class>, but internally it
739 implements many things differently. This may change in the future.
740
741 =head1 INHERITANCE
742
743 C<Moose::Meta::Role> is a subclass of L<Class::MOP::Module>.
744
745 =head1 METHODS
746
747 =head2 Construction
748
749 =over 4
750
751 =item B<< Moose::Meta::Role->initialize($role_name) >>
752
753 This method creates a new role object with the provided name.
754
755 =item B<< Moose::Meta::Role->combine( [ $role => { ... } ], [ $role ], ... ) >>
756
757 This method accepts a list of array references. Each array reference
758 should contain a role name or L<Moose::Meta::Role> object as its first element. The second element is
759 an optional hash reference. The hash reference can contain C<-excludes>
760 and C<-alias> keys to control how methods are composed from the role.
761
762 The return value is a new L<Moose::Meta::Role::Composite> that
763 represents the combined roles.
764
765 =item B<< $metarole->composition_class_roles >>
766
767 When combining multiple roles using C<combine>, this method is used to obtain a
768 list of role names to be applied to the L<Moose::Meta::Role::Composite>
769 instance returned by C<combine>. The default implementation returns an empty
770 list. Extensions that need to hook into role combination may wrap this method
771 to return additional role names.
772
773 =item B<< Moose::Meta::Role->create($name, %options) >>
774
775 This method is identical to the L<Moose::Meta::Class> C<create>
776 method.
777
778 =item B<< Moose::Meta::Role->create_anon_role >>
779
780 This method is identical to the L<Moose::Meta::Class>
781 C<create_anon_class> method.
782
783 =item B<< $metarole->is_anon_role >>
784
785 Returns true if the role is an anonymous role.
786
787 =item B<< $metarole->consumers >>
788
789 Returns a list of names of classes and roles which consume this role.
790
791 =back
792
793 =head2 Role application
794
795 =over 4
796
797 =item B<< $metarole->apply( $thing, @options ) >>
798
799 This method applies a role to the given C<$thing>. That can be another
800 L<Moose::Meta::Role>, object, a L<Moose::Meta::Class> object, or a
801 (non-meta) object instance.
802
803 The options are passed directly to the constructor for the appropriate
804 L<Moose::Meta::Role::Application> subclass.
805
806 Note that this will apply the role even if the C<$thing> in question already
807 C<does> this role.  L<Moose::Util/does_role> is a convenient wrapper for
808 finding out if role application is necessary.
809
810 =back
811
812 =head2 Roles and other roles
813
814 =over 4
815
816 =item B<< $metarole->get_roles >>
817
818 This returns an array reference of roles which this role does. This
819 list may include duplicates.
820
821 =item B<< $metarole->calculate_all_roles >>
822
823 This returns a I<unique> list of all roles that this role does, and
824 all the roles that its roles do.
825
826 =item B<< $metarole->does_role($role) >>
827
828 Given a role I<name> or L<Moose::Meta::Role> object, returns true if this role
829 does the given role.
830
831 =item B<< $metarole->add_role($role) >>
832
833 Given a L<Moose::Meta::Role> object, this adds the role to the list of
834 roles that the role does.
835
836 =item B<< $metarole->get_excluded_roles_list >>
837
838 Returns a list of role names which this role excludes.
839
840 =item B<< $metarole->excludes_role($role_name) >>
841
842 Given a role I<name>, returns true if this role excludes the named
843 role.
844
845 =item B<< $metarole->add_excluded_roles(@role_names) >>
846
847 Given one or more role names, adds those roles to the list of excluded
848 roles.
849
850 =back
851
852 =head2 Methods
853
854 The methods for dealing with a role's methods are all identical in API
855 and behavior to the same methods in L<Class::MOP::Class>.
856
857 =over 4
858
859 =item B<< $metarole->method_metaclass >>
860
861 Returns the method metaclass name for the role. This defaults to
862 L<Moose::Meta::Role::Method>.
863
864 =item B<< $metarole->get_method($name) >>
865
866 =item B<< $metarole->has_method($name) >>
867
868 =item B<< $metarole->add_method( $name, $body ) >>
869
870 =item B<< $metarole->get_method_list >>
871
872 =item B<< $metarole->find_method_by_name($name) >>
873
874 These methods are all identical to the methods of the same name in
875 L<Class::MOP::Package>
876
877 =back
878
879 =head2 Attributes
880
881 As with methods, the methods for dealing with a role's attribute are
882 all identical in API and behavior to the same methods in
883 L<Class::MOP::Class>.
884
885 However, attributes stored in this class are I<not> stored as
886 objects. Rather, the attribute definition is stored as a hash
887 reference. When a role is composed into a class, this hash reference
888 is passed directly to the metaclass's C<add_attribute> method.
889
890 This is quite likely to change in the future.
891
892 =over 4
893
894 =item B<< $metarole->get_attribute($attribute_name) >>
895
896 =item B<< $metarole->has_attribute($attribute_name) >>
897
898 =item B<< $metarole->get_attribute_list >>
899
900 =item B<< $metarole->add_attribute($name, %options) >>
901
902 =item B<< $metarole->remove_attribute($attribute_name) >>
903
904 =back
905
906 =head2 Overload introspection and creation
907
908 The methods for dealing with a role's overloads are all identical in API
909 and behavior to the same methods in L<Class::MOP::Class>. Note that these are
910 not particularly useful (yet), because overloads do not participate in role
911 composition.
912
913 =over 4
914
915 =item B<< $metarole->is_overloaded >>
916
917 =item B<< $metarole->get_overloaded_operator($op) >>
918
919 =item B<< $metarole->has_overloaded_operator($op) >>
920
921 =item B<< $metarole->get_overload_list >>
922
923 =item B<< $metarole->get_all_overloaded_operators >>
924
925 =item B<< $metarole->add_overloaded_operator($op, $impl) >>
926
927 =item B<< $metarole->remove_overloaded_operator($op) >>
928
929 =back
930
931 =head2 Required methods
932
933 =over 4
934
935 =item B<< $metarole->get_required_method_list >>
936
937 Returns the list of methods required by the role.
938
939 =item B<< $metarole->requires_method($name) >>
940
941 Returns true if the role requires the named method.
942
943 =item B<< $metarole->add_required_methods(@names) >>
944
945 Adds the named methods to the role's list of required methods.
946
947 =item B<< $metarole->remove_required_methods(@names) >>
948
949 Removes the named methods from the role's list of required methods.
950
951 =item B<< $metarole->add_conflicting_method(%params) >>
952
953 Instantiate the parameters as a L<Moose::Meta::Role::Method::Conflicting>
954 object, then add it to the required method list.
955
956 =back
957
958 =head2 Method modifiers
959
960 These methods act like their counterparts in L<Class::MOP::Class> and
961 L<Moose::Meta::Class>.
962
963 However, method modifiers are simply stored internally, and are not
964 applied until the role itself is applied to a class.
965
966 =over 4
967
968 =item B<< $metarole->add_after_method_modifier($method_name, $method) >>
969
970 =item B<< $metarole->add_around_method_modifier($method_name, $method) >>
971
972 =item B<< $metarole->add_before_method_modifier($method_name, $method) >>
973
974 =item B<< $metarole->add_override_method_modifier($method_name, $method) >>
975
976 These methods all add an appropriate modifier to the internal list of
977 modifiers.
978
979 =item B<< $metarole->has_after_method_modifiers >>
980
981 =item B<< $metarole->has_around_method_modifiers >>
982
983 =item B<< $metarole->has_before_method_modifiers >>
984
985 =item B<< $metarole->has_override_method_modifier >>
986
987 Return true if the role has any modifiers of the given type.
988
989 =item B<< $metarole->get_after_method_modifiers($method_name) >>
990
991 =item B<< $metarole->get_around_method_modifiers($method_name) >>
992
993 =item B<< $metarole->get_before_method_modifiers($method_name) >>
994
995 Given a method name, returns a list of the appropriate modifiers for
996 that method.
997
998 =item B<< $metarole->get_override_method_modifier($method_name) >>
999
1000 Given a method name, returns the override method modifier for that
1001 method, if it has one.
1002
1003 =back
1004
1005 =head2 Introspection
1006
1007 =over 4
1008
1009 =item B<< Moose::Meta::Role->meta >>
1010
1011 This will return a L<Class::MOP::Class> instance for this class.
1012
1013 =back
1014
1015 =head1 BUGS
1016
1017 See L<Moose/BUGS> for details on reporting bugs.
1018
1019 =cut