<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package Moose::Meta::Role;
BEGIN {
  $Moose::Meta::Role::AUTHORITY = 'cpan:STEVAN';
}
{
  $Moose::Meta::Role::VERSION = '2.0603';
}

use strict;
use warnings;
use metaclass;

use Class::Load qw(load_class);
use Scalar::Util 'blessed';
use Carp         'confess';
use Devel::GlobalDestruction 'in_global_destruction';

use Moose::Meta::Class;
use Moose::Meta::Role::Attribute;
use Moose::Meta::Role::Method;
use Moose::Meta::Role::Method::Required;
use Moose::Meta::Role::Method::Conflicting;
use Moose::Meta::Method::Meta;
use Moose::Util qw( ensure_all_roles );
use Class::MOP::MiniTrait;

use base 'Class::MOP::Module',
         'Class::MOP::Mixin::HasAttributes',
         'Class::MOP::Mixin::HasMethods';

Class::MOP::MiniTrait::apply(__PACKAGE__, 'Moose::Meta::Object::Trait');

## ------------------------------------------------------------------
## NOTE:
## I normally don't do this, but I am doing
## a whole bunch of meta-programmin in this
## module, so it just makes sense. For a clearer
## picture of what is going on in the next
## several lines of code, look at the really
## big comment at the end of this file (right
## before the POD).
## - SL
## ------------------------------------------------------------------

my $META = __PACKAGE__-&gt;meta;

## ------------------------------------------------------------------
## attributes ...

# NOTE:
# since roles are lazy, we hold all the attributes
# of the individual role in 'stasis' until which
# time when it is applied to a class. This means
# keeping a lot of things in hash maps, so we are
# using a little of that meta-programmin' magic
# here an saving lots of extra typin. And since
# many of these attributes above require similar
# functionality to support them, so we again use
# the wonders of meta-programmin' to deliver a
# very compact solution to this normally verbose
# problem.
# - SL

foreach my $action (
    {
        name        =&gt; 'excluded_roles_map',
        attr_reader =&gt; 'get_excluded_roles_map' ,
        methods     =&gt; {
            add       =&gt; 'add_excluded_roles',
            get_keys  =&gt; 'get_excluded_roles_list',
            existence =&gt; 'excludes_role',
        }
    },
    {
        name        =&gt; 'required_methods',
        attr_reader =&gt; 'get_required_methods_map',
        methods     =&gt; {
            remove     =&gt; 'remove_required_methods',
            get_values =&gt; 'get_required_method_list',
            existence  =&gt; 'requires_method',
        }
    },
) {

    my $attr_reader = $action-&gt;{attr_reader};
    my $methods     = $action-&gt;{methods};

    # create the attribute
    $META-&gt;add_attribute($action-&gt;{name} =&gt; (
        reader  =&gt; $attr_reader,
        default =&gt; sub { {} },
        Class::MOP::_definition_context(),
    ));

    # create some helper methods
    $META-&gt;add_method($methods-&gt;{add} =&gt; sub {
        my ($self, @values) = @_;
        $self-&gt;$attr_reader-&gt;{$_} = undef foreach @values;
    }) if exists $methods-&gt;{add};

    $META-&gt;add_method($methods-&gt;{get_keys} =&gt; sub {
        my ($self) = @_;
        keys %{$self-&gt;$attr_reader};
    }) if exists $methods-&gt;{get_keys};

    $META-&gt;add_method($methods-&gt;{get_values} =&gt; sub {
        my ($self) = @_;
        values %{$self-&gt;$attr_reader};
    }) if exists $methods-&gt;{get_values};

    $META-&gt;add_method($methods-&gt;{get} =&gt; sub {
        my ($self, $name) = @_;
        $self-&gt;$attr_reader-&gt;{$name}
    }) if exists $methods-&gt;{get};

    $META-&gt;add_method($methods-&gt;{existence} =&gt; sub {
        my ($self, $name) = @_;
        exists $self-&gt;$attr_reader-&gt;{$name} ? 1 : 0;
    }) if exists $methods-&gt;{existence};

    $META-&gt;add_method($methods-&gt;{remove} =&gt; sub {
        my ($self, @values) = @_;
        delete $self-&gt;$attr_reader-&gt;{$_} foreach @values;
    }) if exists $methods-&gt;{remove};
}

$META-&gt;add_attribute(
    'method_metaclass',
    reader  =&gt; 'method_metaclass',
    default =&gt; 'Moose::Meta::Role::Method',
    Class::MOP::_definition_context(),
);

$META-&gt;add_attribute(
    'required_method_metaclass',
    reader  =&gt; 'required_method_metaclass',
    default =&gt; 'Moose::Meta::Role::Method::Required',
    Class::MOP::_definition_context(),
);

$META-&gt;add_attribute(
    'conflicting_method_metaclass',
    reader  =&gt; 'conflicting_method_metaclass',
    default =&gt; 'Moose::Meta::Role::Method::Conflicting',
    Class::MOP::_definition_context(),
);

$META-&gt;add_attribute(
    'application_to_class_class',
    reader  =&gt; 'application_to_class_class',
    default =&gt; 'Moose::Meta::Role::Application::ToClass',
    Class::MOP::_definition_context(),
);

$META-&gt;add_attribute(
    'application_to_role_class',
    reader  =&gt; 'application_to_role_class',
    default =&gt; 'Moose::Meta::Role::Application::ToRole',
    Class::MOP::_definition_context(),
);

$META-&gt;add_attribute(
    'application_to_instance_class',
    reader  =&gt; 'application_to_instance_class',
    default =&gt; 'Moose::Meta::Role::Application::ToInstance',
    Class::MOP::_definition_context(),
);

$META-&gt;add_attribute(
    'applied_attribute_metaclass',
    reader  =&gt; 'applied_attribute_metaclass',
    default =&gt; 'Moose::Meta::Attribute',
    Class::MOP::_definition_context(),
);

# More or less copied from Moose::Meta::Class
sub initialize {
    my $class = shift;
    my @args = @_;
    unshift @args, 'package' if @args % 2;
    my %opts = @args;
    my $package = delete $opts{package};
    return Class::MOP::get_metaclass_by_name($package)
        || $class-&gt;SUPER::initialize($package,
                'attribute_metaclass' =&gt; 'Moose::Meta::Role::Attribute',
                %opts,
            );
}

sub reinitialize {
    my $self = shift;
    my $pkg  = shift;

    my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg);

    my %existing_classes;
    if ($meta) {
        %existing_classes = map { $_ =&gt; $meta-&gt;$_() } qw(
            attribute_metaclass
            method_metaclass
            wrapped_method_metaclass
            required_method_metaclass
            conflicting_method_metaclass
            application_to_class_class
            application_to_role_class
            application_to_instance_class
            applied_attribute_metaclass
        );
    }

    my %options = @_;
    $options{weaken} = Class::MOP::metaclass_is_weak($meta-&gt;name)
        if !exists $options{weaken}
        &amp;&amp; blessed($meta)
        &amp;&amp; $meta-&gt;isa('Moose::Meta::Role');

    # don't need to remove generated metaobjects here yet, since we don't
    # yet generate anything in roles. this may change in the future though...
    # keep an eye on that
    my $new_meta = $self-&gt;SUPER::reinitialize(
        $pkg,
        %existing_classes,
        %options,
    );
    $new_meta-&gt;_restore_metaobjects_from($meta)
        if $meta &amp;&amp; $meta-&gt;isa('Moose::Meta::Role');
    return $new_meta;
}

sub _restore_metaobjects_from {
    my $self = shift;
    my ($old_meta) = @_;

    $self-&gt;_restore_metamethods_from($old_meta);
    $self-&gt;_restore_metaattributes_from($old_meta);

    for my $role ( @{ $old_meta-&gt;get_roles } ) {
        $self-&gt;add_role($role);
    }
}

sub add_attribute {
    my $self = shift;

    if (blessed $_[0] &amp;&amp; ! $_[0]-&gt;isa('Moose::Meta::Role::Attribute') ) {
        my $class = ref $_[0];
        Moose-&gt;throw_error( "Cannot add a $class as an attribute to a role" );
    }
    elsif (!blessed($_[0]) &amp;&amp; defined($_[0]) &amp;&amp; $_[0] =~ /^\+(.*)/) {
        Moose-&gt;throw_error( "has '+attr' is not supported in roles" );
    }

    return $self-&gt;SUPER::add_attribute(@_);
}

sub _attach_attribute {
    my ( $self, $attribute ) = @_;

    $attribute-&gt;attach_to_role($self);
}

sub add_required_methods {
    my $self = shift;

    for (@_) {
        my $method = $_;
        if (!blessed($method)) {
            $method = $self-&gt;required_method_metaclass-&gt;new(
                name =&gt; $method,
            );
        }
        $self-&gt;get_required_methods_map-&gt;{$method-&gt;name} = $method;
    }
}

sub add_conflicting_method {
    my $self = shift;

    my $method;
    if (@_ == 1 &amp;&amp; blessed($_[0])) {
        $method = shift;
    }
    else {
        $method = $self-&gt;conflicting_method_metaclass-&gt;new(@_);
    }

    $self-&gt;add_required_methods($method);
}

## ------------------------------------------------------------------
## method modifiers

# NOTE:
# the before/around/after method modifiers are
# stored by name, but there can be many methods
# then associated with that name. So again we have
# lots of similar functionality, so we can do some
# meta-programmin' and save some time.
# - SL

foreach my $modifier_type (qw[ before around after ]) {

    my $attr_reader = "get_${modifier_type}_method_modifiers_map";

    # create the attribute ...
    $META-&gt;add_attribute("${modifier_type}_method_modifiers" =&gt; (
        reader  =&gt; $attr_reader,
        default =&gt; sub { {} },
        Class::MOP::_definition_context(),
    ));

    # and some helper methods ...
    $META-&gt;add_method("get_${modifier_type}_method_modifiers" =&gt; sub {
        my ($self, $method_name) = @_;
        #return () unless exists $self-&gt;$attr_reader-&gt;{$method_name};
        my $mm = $self-&gt;$attr_reader-&gt;{$method_name};
        $mm ? @$mm : ();
    });

    $META-&gt;add_method("has_${modifier_type}_method_modifiers" =&gt; sub {
        my ($self, $method_name) = @_;
        # NOTE:
        # for now we assume that if it exists,..
        # it has at least one modifier in it
        (exists $self-&gt;$attr_reader-&gt;{$method_name}) ? 1 : 0;
    });

    $META-&gt;add_method("add_${modifier_type}_method_modifier" =&gt; sub {
        my ($self, $method_name, $method) = @_;

        $self-&gt;$attr_reader-&gt;{$method_name} = []
            unless exists $self-&gt;$attr_reader-&gt;{$method_name};

        my $modifiers = $self-&gt;$attr_reader-&gt;{$method_name};

        # NOTE:
        # check to see that we aren't adding the
        # same code twice. We err in favor of the
        # first on here, this may not be as expected
        foreach my $modifier (@{$modifiers}) {
            return if $modifier == $method;
        }

        push @{$modifiers} =&gt; $method;
    });

}

## ------------------------------------------------------------------
## override method mofidiers

$META-&gt;add_attribute('override_method_modifiers' =&gt; (
    reader  =&gt; 'get_override_method_modifiers_map',
    default =&gt; sub { {} },
    Class::MOP::_definition_context(),
));

# NOTE:
# these are a little different because there
# can only be one per name, whereas the other
# method modifiers can have multiples.
# - SL

sub add_override_method_modifier {
    my ($self, $method_name, $method) = @_;
    (!$self-&gt;has_method($method_name))
        || Moose-&gt;throw_error("Cannot add an override of method '$method_name' " .
                   "because there is a local version of '$method_name'");
    $self-&gt;get_override_method_modifiers_map-&gt;{$method_name} = $method;
}

sub has_override_method_modifier {
    my ($self, $method_name) = @_;
    # NOTE:
    # for now we assume that if it exists,..
    # it has at least one modifier in it
    (exists $self-&gt;get_override_method_modifiers_map-&gt;{$method_name}) ? 1 : 0;
}

sub get_override_method_modifier {
    my ($self, $method_name) = @_;
    $self-&gt;get_override_method_modifiers_map-&gt;{$method_name};
}

## general list accessor ...

sub get_method_modifier_list {
    my ($self, $modifier_type) = @_;
    my $accessor = "get_${modifier_type}_method_modifiers_map";
    keys %{$self-&gt;$accessor};
}

sub _meta_method_class { 'Moose::Meta::Method::Meta' }

## ------------------------------------------------------------------
## subroles

$META-&gt;add_attribute('roles' =&gt; (
    reader  =&gt; 'get_roles',
    default =&gt; sub { [] },
    Class::MOP::_definition_context(),
));

sub add_role {
    my ($self, $role) = @_;
    (blessed($role) &amp;&amp; $role-&gt;isa('Moose::Meta::Role'))
        || Moose-&gt;throw_error("Roles must be instances of Moose::Meta::Role");
    push @{$self-&gt;get_roles} =&gt; $role;
    $self-&gt;reset_package_cache_flag;
}

sub calculate_all_roles {
    my $self = shift;
    my %seen;
    grep {
        !$seen{$_-&gt;name}++
    } ($self, map {
                  $_-&gt;calculate_all_roles
              } @{ $self-&gt;get_roles });
}

sub does_role {
    my ($self, $role) = @_;
    (defined $role)
        || Moose-&gt;throw_error("You must supply a role name to look for");
    my $role_name = blessed $role ? $role-&gt;name : $role;
    # if we are it,.. then return true
    return 1 if $role_name eq $self-&gt;name;
    # otherwise.. check our children
    foreach my $role (@{$self-&gt;get_roles}) {
        return 1 if $role-&gt;does_role($role_name);
    }
    return 0;
}

sub find_method_by_name { (shift)-&gt;get_method(@_) }

## ------------------------------------------------------------------
## role construction
## ------------------------------------------------------------------

sub apply {
    my ($self, $other, %args) = @_;

    (blessed($other))
        || Moose-&gt;throw_error("You must pass in an blessed instance");

    my $application_class;
    if ($other-&gt;isa('Moose::Meta::Role')) {
        $application_class = $self-&gt;application_to_role_class;
    }
    elsif ($other-&gt;isa('Moose::Meta::Class')) {
        $application_class = $self-&gt;application_to_class_class;
    }
    else {
        $application_class = $self-&gt;application_to_instance_class;
    }

    load_class($application_class);

    if ( exists $args{'-excludes'} ) {
        # I wish we had coercion here :)
        $args{'-excludes'} = (
            ref $args{'-excludes'} eq 'ARRAY'
            ? $args{'-excludes'}
            : [ $args{'-excludes'} ]
        );
    }

    return $application_class-&gt;new(%args)-&gt;apply($self, $other, \%args);
}

sub composition_class_roles { }

sub combine {
    my ($class, @role_specs) = @_;

    require Moose::Meta::Role::Composite;

    my (@roles, %role_params);
    while (@role_specs) {
        my ($role, $params) = @{ splice @role_specs, 0, 1 };
        my $requested_role
            = blessed $role
            ? $role
            : Class::MOP::class_of($role);

        my $actual_role = $requested_role-&gt;_role_for_combination($params);
        push @roles =&gt; $actual_role;

        next unless defined $params;
        $role_params{$actual_role-&gt;name} = $params;
    }

    my $c = Moose::Meta::Role::Composite-&gt;new(roles =&gt; \@roles);
    return $c-&gt;apply_params(\%role_params);
}

sub _role_for_combination {
    my ($self, $params) = @_;
    return $self;
}

sub create {
    my $class = shift;
    my @args = @_;

    unshift @args, 'package' if @args % 2 == 1;
    my %options = @args;

    (ref $options{attributes} eq 'HASH')
        || confess "You must pass a HASH ref of attributes"
            if exists $options{attributes};

    (ref $options{methods} eq 'HASH')
        || confess "You must pass a HASH ref of methods"
            if exists $options{methods};

    (ref $options{roles} eq 'ARRAY')
        || confess "You must pass an ARRAY ref of roles"
            if exists $options{roles};

    my $package      = delete $options{package};
    my $roles        = delete $options{roles};
    my $attributes   = delete $options{attributes};
    my $methods      = delete $options{methods};
    my $meta_name    = exists $options{meta_name}
                         ? delete $options{meta_name}
                         : 'meta';

    my $meta = $class-&gt;SUPER::create($package =&gt; %options);

    $meta-&gt;_add_meta_method($meta_name)
        if defined $meta_name;

    if (defined $attributes) {
        foreach my $attribute_name (keys %{$attributes}) {
            my $attr = $attributes-&gt;{$attribute_name};
            $meta-&gt;add_attribute(
                $attribute_name =&gt; blessed $attr ? $attr : %{$attr} );
        }
    }

    if (defined $methods) {
        foreach my $method_name (keys %{$methods}) {
            $meta-&gt;add_method($method_name, $methods-&gt;{$method_name});
        }
    }

    if ($roles) {
        Moose::Util::apply_all_roles($meta, @$roles);
    }

    return $meta;
}

sub consumers {
    my $self = shift;
    my @consumers;
    for my $meta (Class::MOP::get_all_metaclass_instances) {
        next if $meta-&gt;name eq $self-&gt;name;
        next unless $meta-&gt;isa('Moose::Meta::Class')
                 || $meta-&gt;isa('Moose::Meta::Role');
        push @consumers, $meta-&gt;name
            if $meta-&gt;does_role($self-&gt;name);
    }
    return @consumers;
}

# XXX: something more intelligent here?
sub _anon_package_prefix { 'Moose::Meta::Role::__ANON__::SERIAL::' }

sub create_anon_role { shift-&gt;create_anon(@_) }
sub is_anon_role     { shift-&gt;is_anon(@_)     }

sub _anon_cache_key {
    my $class = shift;
    my %options = @_;

    # XXX fix this duplication (see MMC::_anon_cache_key
    my $roles = Data::OptList::mkopt(($options{roles} || []), {
        moniker  =&gt; 'role',
        val_test =&gt; sub { ref($_[0]) eq 'HASH' },
    });

    my @role_keys;
    for my $role_spec (@$roles) {
        my ($role, $params) = @$role_spec;
        $params = { %$params };

        my $key = blessed($role) ? $role-&gt;name : $role;

        if ($params &amp;&amp; %$params) {
            my $alias    = delete $params-&gt;{'-alias'}
                        || delete $params-&gt;{'alias'}
                        || {};
            my $excludes = delete $params-&gt;{'-excludes'}
                        || delete $params-&gt;{'excludes'}
                        || [];
            $excludes = [$excludes] unless ref($excludes) eq 'ARRAY';

            if (%$params) {
                warn "Roles with parameters cannot be cached. Consider "
                   . "applying the parameters before calling "
                   . "create_anon_class, or using 'weaken =&gt; 0' instead";
                return;
            }

            my $alias_key = join('%',
                map { $_ =&gt; $alias-&gt;{$_} } sort keys %$alias
            );
            my $excludes_key = join('%',
                sort @$excludes
            );
            $key .= '&lt;' . join('+', 'a', $alias_key, 'e', $excludes_key) . '&gt;';
        }

        push @role_keys, $key;
    }

    # Makes something like Role|Role::1
    return join('|', sort @role_keys);
}

#####################################################################
## NOTE:
## This is Moose::Meta::Role as defined by Moose (plus the use of
## MooseX::AttributeHelpers module). It is here as a reference to
## make it easier to see what is happening above with all the meta
## programming. - SL
#####################################################################
#
# has 'roles' =&gt; (
#     metaclass =&gt; 'Array',
#     reader    =&gt; 'get_roles',
#     isa       =&gt; 'ArrayRef[Moose::Meta::Role]',
#     default   =&gt; sub { [] },
#     provides  =&gt; {
#         'push' =&gt; 'add_role',
#     }
# );
#
# has 'excluded_roles_map' =&gt; (
#     metaclass =&gt; 'Hash',
#     reader    =&gt; 'get_excluded_roles_map',
#     isa       =&gt; 'HashRef[Str]',
#     provides  =&gt; {
#         # Not exactly set, cause it sets multiple
#         'set'    =&gt; 'add_excluded_roles',
#         'keys'   =&gt; 'get_excluded_roles_list',
#         'exists' =&gt; 'excludes_role',
#     }
# );
#
# has 'required_methods' =&gt; (
#     metaclass =&gt; 'Hash',
#     reader    =&gt; 'get_required_methods_map',
#     isa       =&gt; 'HashRef[Moose::Meta::Role::Method::Required]',
#     provides  =&gt; {
#         # not exactly set, or delete since it works for multiple
#         'set'    =&gt; 'add_required_methods',
#         'delete' =&gt; 'remove_required_methods',
#         'keys'   =&gt; 'get_required_method_list',
#         'exists' =&gt; 'requires_method',
#     }
# );
#
# # the before, around and after modifiers are
# # HASH keyed by method-name, with ARRAY of
# # CODE refs to apply in that order
#
# has 'before_method_modifiers' =&gt; (
#     metaclass =&gt; 'Hash',
#     reader    =&gt; 'get_before_method_modifiers_map',
#     isa       =&gt; 'HashRef[ArrayRef[CodeRef]]',
#     provides  =&gt; {
#         'keys'   =&gt; 'get_before_method_modifiers',
#         'exists' =&gt; 'has_before_method_modifiers',
#         # This actually makes sure there is an
#         # ARRAY at the given key, and pushed onto
#         # it. It also checks for duplicates as well
#         # 'add'  =&gt; 'add_before_method_modifier'
#     }
# );
#
# has 'after_method_modifiers' =&gt; (
#     metaclass =&gt; 'Hash',
#     reader    =&gt;'get_after_method_modifiers_map',
#     isa       =&gt; 'HashRef[ArrayRef[CodeRef]]',
#     provides  =&gt; {
#         'keys'   =&gt; 'get_after_method_modifiers',
#         'exists' =&gt; 'has_after_method_modifiers',
#         # This actually makes sure there is an
#         # ARRAY at the given key, and pushed onto
#         # it. It also checks for duplicates as well
#         # 'add'  =&gt; 'add_after_method_modifier'
#     }
# );
#
# has 'around_method_modifiers' =&gt; (
#     metaclass =&gt; 'Hash',
#     reader    =&gt;'get_around_method_modifiers_map',
#     isa       =&gt; 'HashRef[ArrayRef[CodeRef]]',
#     provides  =&gt; {
#         'keys'   =&gt; 'get_around_method_modifiers',
#         'exists' =&gt; 'has_around_method_modifiers',
#         # This actually makes sure there is an
#         # ARRAY at the given key, and pushed onto
#         # it. It also checks for duplicates as well
#         # 'add'  =&gt; 'add_around_method_modifier'
#     }
# );
#
# # override is similar to the other modifiers
# # except that it is not an ARRAY of code refs
# # but instead just a single name-&gt;code mapping
#
# has 'override_method_modifiers' =&gt; (
#     metaclass =&gt; 'Hash',
#     reader    =&gt;'get_override_method_modifiers_map',
#     isa       =&gt; 'HashRef[CodeRef]',
#     provides  =&gt; {
#         'keys'   =&gt; 'get_override_method_modifier',
#         'exists' =&gt; 'has_override_method_modifier',
#         'add'    =&gt; 'add_override_method_modifier', # checks for local method ..
#     }
# );
#
#####################################################################


1;

# ABSTRACT: The Moose Role metaclass



=pod

=head1 NAME

Moose::Meta::Role - The Moose Role metaclass

=head1 VERSION

version 2.0603

=head1 DESCRIPTION

This class is a subclass of L&lt;Class::MOP::Module&gt; that provides
additional Moose-specific functionality.

Its API looks a lot like L&lt;Moose::Meta::Class&gt;, but internally it
implements many things differently. This may change in the future.

=head1 INHERITANCE

C&lt;Moose::Meta::Role&gt; is a subclass of L&lt;Class::MOP::Module&gt;.

=head1 METHODS

=head2 Construction

=over 4

=item B&lt;&lt; Moose::Meta::Role-&gt;initialize($role_name) &gt;&gt;

This method creates a new role object with the provided name.

=item B&lt;&lt; Moose::Meta::Role-&gt;combine( [ $role =&gt; { ... } ], [ $role ], ... ) &gt;&gt;

This method accepts a list of array references. Each array reference
should contain a role name or L&lt;Moose::Meta::Role&gt; object as its first element. The second element is
an optional hash reference. The hash reference can contain C&lt;-excludes&gt;
and C&lt;-alias&gt; keys to control how methods are composed from the role.

The return value is a new L&lt;Moose::Meta::Role::Composite&gt; that
represents the combined roles.

=item B&lt;&lt; $metarole-&gt;composition_class_roles &gt;&gt;

When combining multiple roles using C&lt;combine&gt;, this method is used to obtain a
list of role names to be applied to the L&lt;Moose::Meta::Role::Composite&gt;
instance returned by C&lt;combine&gt;. The default implementation returns an empty
list. Extensions that need to hook into role combination may wrap this method
to return additional role names.

=item B&lt;&lt; Moose::Meta::Role-&gt;create($name, %options) &gt;&gt;

This method is identical to the L&lt;Moose::Meta::Class&gt; C&lt;create&gt;
method.

=item B&lt;&lt; Moose::Meta::Role-&gt;create_anon_role &gt;&gt;

This method is identical to the L&lt;Moose::Meta::Class&gt;
C&lt;create_anon_class&gt; method.

=item B&lt;&lt; $metarole-&gt;is_anon_role &gt;&gt;

Returns true if the role is an anonymous role.

=item B&lt;&lt; $metarole-&gt;consumers &gt;&gt;

Returns a list of names of classes and roles which consume this role.

=back

=head2 Role application

=over 4

=item B&lt;&lt; $metarole-&gt;apply( $thing, @options ) &gt;&gt;

This method applies a role to the given C&lt;$thing&gt;. That can be another
L&lt;Moose::Meta::Role&gt;, object, a L&lt;Moose::Meta::Class&gt; object, or a
(non-meta) object instance.

The options are passed directly to the constructor for the appropriate
L&lt;Moose::Meta::Role::Application&gt; subclass.

Note that this will apply the role even if the C&lt;$thing&gt; in question already
C&lt;does&gt; this role.  L&lt;Moose::Util/does_role&gt; is a convenient wrapper for
finding out if role application is necessary.

=back

=head2 Roles and other roles

=over 4

=item B&lt;&lt; $metarole-&gt;get_roles &gt;&gt;

This returns an array reference of roles which this role does. This
list may include duplicates.

=item B&lt;&lt; $metarole-&gt;calculate_all_roles &gt;&gt;

This returns a I&lt;unique&gt; list of all roles that this role does, and
all the roles that its roles do.

=item B&lt;&lt; $metarole-&gt;does_role($role) &gt;&gt;

Given a role I&lt;name&gt; or L&lt;Moose::Meta::Role&gt; object, returns true if this role
does the given role.

=item B&lt;&lt; $metarole-&gt;add_role($role) &gt;&gt;

Given a L&lt;Moose::Meta::Role&gt; object, this adds the role to the list of
roles that the role does.

=item B&lt;&lt; $metarole-&gt;get_excluded_roles_list &gt;&gt;

Returns a list of role names which this role excludes.

=item B&lt;&lt; $metarole-&gt;excludes_role($role_name) &gt;&gt;

Given a role I&lt;name&gt;, returns true if this role excludes the named
role.

=item B&lt;&lt; $metarole-&gt;add_excluded_roles(@role_names) &gt;&gt;

Given one or more role names, adds those roles to the list of excluded
roles.

=back

=head2 Methods

The methods for dealing with a role's methods are all identical in API
and behavior to the same methods in L&lt;Class::MOP::Class&gt;.

=over 4

=item B&lt;&lt; $metarole-&gt;method_metaclass &gt;&gt;

Returns the method metaclass name for the role. This defaults to
L&lt;Moose::Meta::Role::Method&gt;.

=item B&lt;&lt; $metarole-&gt;get_method($name) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;has_method($name) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;add_method( $name, $body ) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;get_method_list &gt;&gt;

=item B&lt;&lt; $metarole-&gt;find_method_by_name($name) &gt;&gt;

These methods are all identical to the methods of the same name in
L&lt;Class::MOP::Package&gt;

=back

=head2 Attributes

As with methods, the methods for dealing with a role's attribute are
all identical in API and behavior to the same methods in
L&lt;Class::MOP::Class&gt;.

However, attributes stored in this class are I&lt;not&gt; stored as
objects. Rather, the attribute definition is stored as a hash
reference. When a role is composed into a class, this hash reference
is passed directly to the metaclass's C&lt;add_attribute&gt; method.

This is quite likely to change in the future.

=over 4

=item B&lt;&lt; $metarole-&gt;get_attribute($attribute_name) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;has_attribute($attribute_name) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;get_attribute_list &gt;&gt;

=item B&lt;&lt; $metarole-&gt;add_attribute($name, %options) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;remove_attribute($attribute_name) &gt;&gt;

=back

=head2 Overload introspection and creation

The methods for dealing with a role's overloads are all identical in API
and behavior to the same methods in L&lt;Class::MOP::Class&gt;. Note that these are
not particularly useful (yet), because overloads do not participate in role
composition.

=over 4

=item B&lt;&lt; $metarole-&gt;is_overloaded &gt;&gt;

=item B&lt;&lt; $metarole-&gt;get_overloaded_operator($op) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;has_overloaded_operator($op) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;get_overload_list &gt;&gt;

=item B&lt;&lt; $metarole-&gt;get_all_overloaded_operators &gt;&gt;

=item B&lt;&lt; $metarole-&gt;add_overloaded_operator($op, $impl) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;remove_overloaded_operator($op) &gt;&gt;

=back

=head2 Required methods

=over 4

=item B&lt;&lt; $metarole-&gt;get_required_method_list &gt;&gt;

Returns the list of methods required by the role.

=item B&lt;&lt; $metarole-&gt;requires_method($name) &gt;&gt;

Returns true if the role requires the named method.

=item B&lt;&lt; $metarole-&gt;add_required_methods(@names) &gt;&gt;

Adds the named methods to the role's list of required methods.

=item B&lt;&lt; $metarole-&gt;remove_required_methods(@names) &gt;&gt;

Removes the named methods from the role's list of required methods.

=item B&lt;&lt; $metarole-&gt;add_conflicting_method(%params) &gt;&gt;

Instantiate the parameters as a L&lt;Moose::Meta::Role::Method::Conflicting&gt;
object, then add it to the required method list.

=back

=head2 Method modifiers

These methods act like their counterparts in L&lt;Class::MOP::Class&gt; and
L&lt;Moose::Meta::Class&gt;.

However, method modifiers are simply stored internally, and are not
applied until the role itself is applied to a class.

=over 4

=item B&lt;&lt; $metarole-&gt;add_after_method_modifier($method_name, $method) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;add_around_method_modifier($method_name, $method) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;add_before_method_modifier($method_name, $method) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;add_override_method_modifier($method_name, $method) &gt;&gt;

These methods all add an appropriate modifier to the internal list of
modifiers.

=item B&lt;&lt; $metarole-&gt;has_after_method_modifiers &gt;&gt;

=item B&lt;&lt; $metarole-&gt;has_around_method_modifiers &gt;&gt;

=item B&lt;&lt; $metarole-&gt;has_before_method_modifiers &gt;&gt;

=item B&lt;&lt; $metarole-&gt;has_override_method_modifier &gt;&gt;

Return true if the role has any modifiers of the given type.

=item B&lt;&lt; $metarole-&gt;get_after_method_modifiers($method_name) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;get_around_method_modifiers($method_name) &gt;&gt;

=item B&lt;&lt; $metarole-&gt;get_before_method_modifiers($method_name) &gt;&gt;

Given a method name, returns a list of the appropriate modifiers for
that method.

=item B&lt;&lt; $metarole-&gt;get_override_method_modifier($method_name) &gt;&gt;

Given a method name, returns the override method modifier for that
method, if it has one.

=back

=head2 Introspection

=over 4

=item B&lt;&lt; Moose::Meta::Role-&gt;meta &gt;&gt;

This will return a L&lt;Class::MOP::Class&gt; instance for this class.

=back

=head1 BUGS

See L&lt;Moose/BUGS&gt; for details on reporting bugs.

=head1 AUTHOR

Moose is maintained by the Moose Cabal, along with the help of many contributors. See L&lt;Moose/CABAL&gt; and L&lt;Moose/CONTRIBUTORS&gt; for details.

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by Infinity Interactive, Inc..

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut


__END__

</pre></body></html>