Moose::...::Roles(3)
Moose::Manual::Roles π
okay bestie, this is the manual page for Moose::Manual::Roles from the User Contributed Perl Documentation collection, and it's giving version 2.4000. Roles, roles, roles β an alternative to deep hierarchies and base classes. Let's GO. π¦
NAME β¨
Moose::Manual::Roles β Roles, an alternative to deep hierarchies and base classes π
VERSION π
version 2.4000
WHAT IS A ROLE? πΈ
Okay so, a role encapsulates some piece of behavior or state that can be shared between classes. It is something that classes do. And like, the most important thing to understand here: roles are not classes. You literally cannot inherit from a role, and a role cannot be instantiated. Periodt. π We sometimes say that roles are consumed, either by classes or by other roles.
Instead, a role is composed into a class. In practical terms, this means all of the methods, method modifiers, and attributes defined in a role are added directly to (we sometimes say "flattened into") the class that consumes the role. These attributes and methods then appear as if they were defined in the class itself. And a subclass of the consuming class will inherit all of these methods and attributes. it's giving inheritance but make it fashion β¨
Moose roles are similar to mixins or interfaces in other languages and are based on the original concept of Traits (http://scg.unibe.ch/research/traits/) for the Smalltalk-80 dialect Squeak. iykyk π§
Besides defining their own methods and attributes, roles can also require that the consuming class define certain methods of its own. You could have a role that consisted only of a list of required methods, in which case the role would be very much like a Java interface. no cap
Note: attribute accessors also count as methods for the purposes of satisfying the requirements of a role. remember that, it comes back later fr fr π
A SIMPLE ROLE π
Creating a role looks a lot like creating a Moose class:
package Breakable;
use Moose::Role;
has 'is_broken' => (
is => 'rw',
isa => 'Bool',
);
sub break {
my $self = shift;
print "I broke\n";
$self->is_broken(1);
}
Except for our use of Moose::Role, this looks just like a class definition with Moose. However, this is not a class, and it cannot be instantiated. Say it with me. Not a class. Cannot be instantiated. π
Instead, its attributes and methods will be composed into classes which use the role:
package Car;
use Moose;
with 'Breakable';
has 'engine' => (
is => 'ro',
isa => 'Engine',
);
The with function composes roles into a class. Once that is done, the Car class has an is_broken attribute and a break method. The Car class also does('Breakable'):
my $car = Car->new( engine => Engine->new );
print $car->is_broken ? 'Busted' : 'Still working';
$car->break;
print $car->is_broken ? 'Busted' : 'Still working';
$car->does('Breakable'); # true
This prints:
Still working
I broke
Busted
We could use this same role in a Bone class:
package Bone;
use Moose;
with 'Breakable';
has 'marrow' => (
is => 'ro',
isa => 'Marrow',
);
See also Moose::Cookbook::Roles::Comparable_CodeReuse for an example. go read it bestie, it slays π«Ά
It's possible to compose existing roles into new roles. For example, we can have a HandleWithCare class which applies both the Breakable and Package roles to any class which consumes it:
package HandleWithCare;
use Moose::Role;
with 'Breakable', 'Package';
roles inside roles, we love to see it πΈβ¨
REQUIRED METHODS π
As mentioned previously, a role can require that consuming classes provide one or more methods. Using our Breakable example, let's make it require that consuming classes implement their own break methods:
package Breakable;
use Moose::Role;
requires 'break';
has 'is_broken' => (
is => 'rw',
isa => 'Bool',
);
after 'break' => sub {
my $self = shift;
$self->is_broken(1);
};
If we try to consume this role in a class that does not have a break method, we will get an exception. π rude but fair
You can see that we added a method modifier on break. We want classes that consume this role to implement their own logic for breaking, but we make sure that the is_broken attribute is always set to true when break is called. best of both worlds, obsessed π
package Car
use Moose;
with 'Breakable';
has 'engine' => (
is => 'ro',
isa => 'Engine',
);
sub break {
my $self = shift;
if ( $self->is_moving ) {
$self->stop;
}
}
Roles Versus Abstract Base Classes π¦
If you are familiar with the concept of abstract base classes in other languages, you may be tempted to use roles in the same way. Lowkey don't though.
You can define an "interface-only" role, one that contains just a list of required methods. yes queen, minimalism
However, any class which consumes this role must implement all of the required methods, either directly or through inheritance from a parent. You cannot delay the method requirement check so that they can be implemented by future subclasses. no postponing, no "we'll deal with it later", it's due TODAY π
Because the role defines the required methods directly, adding a base class to the mix would not achieve anything. We recommend that you simply consume the interface role in each class which implements that interface. clean, simple, iconic β¨
CONSUMING ROLES π
Roles are consumed using the with function.
Most of the time, you should only use one with, even if you are consuming multiple roles. If you consume roles using multiple with statements Moose cannot detect method conflicts between those roles. and you do NOT want mystery conflicts bestie π
Roles can be consumed by classes or by other roles. When a class consumes a role which in turn consumes other roles, the class gets all of the roles applied at once. it's giving cascade, it's giving chain reaction π¦
Required Methods Provided by Attributes π
As mentioned before, a role's required method may also be satisfied by an attribute accessor. BUT. However, the call to has which defines an attribute happens at runtime. This means that you must define the attribute before consuming the role, or else the role will not see the generated accessor. order matters, okay? π These attributes are Moose Attributes.
package Breakable;
use Moose::Role;
requires 'stress';
########
package Car;
use Moose;
has 'stress' => (
is => 'ro',
isa => 'Int',
);
with 'Breakable';
In general, we recommend that you always consume roles after declaring all your attributes. rule of thumb, tattoo it on your brain π§ β¨
It may also be the case that a class wants to consume two roles where one role has an attribute providing a required method for another. For example:
package Breakable;
use Moose::Role;
requires 'stress';
########
package Stressable;
use Moose::Role;
has 'stress' => (
is => 'ro',
isa => 'Int',
);
########
package Car;
use Moose;
# XXX - this will not work
with 'Breakable', 'Stressable';
However, this won't work. The problem is that the accessor methods created for the stress attribute won't be present in the class when the required method checks are done. timing is everything and this timing is a disaster π
There are two possible workarounds. The recommended one is to use stub subroutine(s) in the role providing the accessor(s):
package Stressable;
use Moose::Role;
sub stress;
has 'stress' => (
is => 'ro',
isa => 'Int',
);
The sub stress; line is called a "forward" declaration in the Perl documentation. It creates what is called a "stub" subroutine, a declaration without a body. This is good enough to satisfy the required method checks done by Moose. The stub will not interfere with the creation of a real subroutine later. slay, a little placeholder that causes zero drama π«Ά
The other alternative is to use two separate calls to with in the consuming class:
package Car;
use Moose;
# Not recommended
with 'Stressable';
with 'Breakable';
Each with is run as it is seen. The first call will consume just the Stressable role, which will add the stress attribute to the Car package, which in turn will create an accessor method named stress. Then when the Breakable role is consumed, the method it requires already exists. problem solved, kind of, mostly πΈ
However, as mentioned earlier, multiple with declarations are not recommended, because method conflicts between the roles cannot be seen. In the example above, if both Stressable and Breakable contained methods of the same name, what would happen is that the version in Stressable would silently override the one in Breakable. silent override = silent betrayal, do not recommend π
USING METHOD MODIFIERS π₯
Method modifiers and roles are a very powerful combination. like, genuinely powerful, main character energy π Often, a role will combine method modifiers and required methods. We already saw one example with our Breakable example.
Method modifiers increase the complexity of roles, because they make the role application order relevant. If a class uses multiple roles, each of which modify the same method, those modifiers will be applied in the same order as the roles are used:
package MovieCar;
use Moose;
extends 'Car';
with 'Breakable', 'ExplodesOnBreakage';
Assuming that the new ExplodesOnBreakage role also has an after modifier on break, the after modifiers will run one after the other. The modifier from Breakable will run first, then the one from ExplodesOnBreakage. queue up in order bestie, no cutting the line π
METHOD CONFLICTS π₯
If a class composes multiple roles, and those roles have methods of the same name, we will have a conflict. In that case, the composing class is required to provide its own method of the same name. you gotta be the adult in the room and settle it yourself π
package Breakdancer;
use Moose::Role;
sub break {
}
If we compose both Breakable and Breakdancer in a class, we must provide our own break method:
package FragileDancer;
use Moose;
with 'Breakable', 'Breakdancer';
sub break { ... }
A role can be a collection of other roles:
package Break::Bundle;
use Moose::Role;
with ('Breakable', 'Breakdancer');
When a role consumes another a role, the consuming role's methods silently win in any conflict, and the consumed role's methods are simply ignored. yep. silently. no warning, no note, just vibes and gone. π
βοΈ METHOD EXCLUSION AND ALIASING βοΈ
Okay so bestie, plot twist: what if FragileDancer wants to call the methods from both of its roles? You can alias them, like:
package FragileDancer;
use Moose;
with 'Breakable' => { -alias => { break => 'break_bone' } },
'Breakdancer' => { -alias => { break => 'break_dance' } };
But here's the catch (and it's giving gotcha) β aliasing a method just makes a copy of it under the new name. So you still gotta kick the original name out:
with 'Breakable' => {
-alias => { break => 'break_bone' },
-excludes => 'break',
},
'Breakdancer' => {
-alias => { break => 'break_dance' },
-excludes => 'break',
};
The excludes parameter stops the break method from ever getting composed into the FragileDancer class, so boom π₯ no conflict. Which means FragileDancer doesn't have to implement its own break method. Slay.
But real talk β this is useful AND it lowkey breaks the contract that's implicit in consuming a role. YourFragileDancerclass does bothBreakableandBreakDancer, but it doesn't provide abreakmethod. If some API out there expects an object doing one of those roles, it's probably expecting it to implement that method. π«
And in some use cases you might alias and exclude methods from roles, but then provide a method of the same name in the class itself. No thoughts, just vibes.
Also see Moose::Cookbook::Roles::Restartable_AdvancedComposition for an example. π
π OVERLOADING π
When a Moose role uses overloading, that overloading gets composed into every class that consumes the role. That includes setting the fallback value for that role's overloading. And just like with methods and attributes, when a role consumes another role, that other role's overloading settings get applied to the role. Chain reaction, honestly. β¨
Just like with methods, you can get conflicts between overloading implementations when multiple roles are all consumed by one class. If two roles both provide different overloading implementations for a given operator β that's a conflict. If two roles both implement overloading and have different fallback values β also a conflict. Both of these get detected when multiple roles are being composed into a class together.
And when a role consumes another role? The consuming role's overloading fallback and operator implementations silently "win" the conflict. πΆ No drama, no warning, it just wins. Periodt.
π« ROLE EXCLUSION π«
A role can straight up declare that it cannot be combined with some other role. Use this with great caution bestie, because it really limits how re-usable the role is. π₯²
package Breakable;
use Moose::Role;
excludes 'BreakDancer';
π§ ADDING A ROLE TO AN OBJECT INSTANCE π§
So sometimes you don't want to add a role to a class β you want it on one specific object instance. Like, maybe you wanna slap debug tracing on exactly one instance while you're hunting down a particular bug. Or maybe you wanna dynamically change objects based on a user's config, as a plugin system. Very main character of you. π
The best way to do this is the apply_all_roles() function from Moose::Util:
use Moose::Util qw( apply_all_roles );
my $car = Car->new;
apply_all_roles( $car, 'Breakable' );
This function can apply more than one role at a time, and it does so using the normal Moose role combination system. We recommend using this function to apply roles to an object. It's literally what Moose uses internally when you call with. π€―
πΈ Handling required attributes for roles. πΈ
Applying some roles will require additional parameters being specified to satisfy them, like this:
{
package Car;
use Moose;
}
{
package Breakable;
use Moose::Role;
has 'breakable_parts' => ( is => 'ro', required => 1 );
}
my $car = Car->new;
# next line dies with: Attribute (breakable_parts) is required
apply_all_roles( $car, 'Breakable' );
So you'd need to pass the extra params at application time instead, like so:
apply_all_roles( $car, 'Breakable' => {
rebless_params => {
# Parameters to 'Breakable'
breakable_parts => [qw( tires wheels windscreen )],
}
});
And obviously (iykyk), this interface is way better simplified as a method on Car:
sub make_breakable {
my ( $self, %params ) = @_;
apply_all_roles($self, 'Breakable', { rebless_params => \%params });
}
my $car = Car->new();
$car->make_breakable( breakable_parts => [qw( tires wheels windscreen )] );
π AUTHORS π
The literal legends who made this happen:
- Stevan Little
<stevan@cpan.org> - Dave Rolsky
<autarch@urth.org> - Jesse Luehrs
<doy@cpan.org> - Shawn M Moore
<sartak@cpan.org> - ΧΧΧΧ Χ§ΧΧ'ΧΧ (Yuval Kogman)
<nothingmuch@woobling.org> - Karen Etheridge
<ether@cpan.org> - Florian Ragwitz
<rafl@debian.org> - Hans Dieter Pearcey
<hdp@cpan.org> - Chris Prather
<chris@prather.org> - Matt S Trout
<mstrout@cpan.org>
π COPYRIGHT AND LICENSE π
This software is copyright (c) 2006 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.
and that's the whole page bestie, you ate it UP π This beauty's running on perl v5.42.0 and got its last glow-up on 2025-07-25. Go forth and compose some roles, you iconic queen ππ¦πΈ
π¦ where this page comes from
- fedora 43: perl-Moose 2.4000-4.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms