Moose::Spec::Role(3)
π Moose::Spec::Role β the formal spec for Role behavior π
okay bestie, buckle up. This is Moose::Spec::Role(3) from the User Contributed Perl Documentation, and it's the β¨formal specβ¨ for how Roles behave. Grab a strawberry π, we're going in.
β¨ VERSION β¨
version 2.4000 β yes she's on 2.4000, iconic.
πΈ DESCRIPTION πΈ
NOTE: This document is currently incomplete.
(not me reading a spec that openly admits it's a WIP π love the honesty tho)
π Components of a Role
π Excluded Roles
A role can carry a list of excluded roles β basically roles it should never be composed with. And it's not just the direct composition you have to worry about, no no. It's also the "inherited" composition. The way that exclusion travels up the chain? yeah, that's the whole point.
This feature was lifted from the Fortress language, and it's genuinely most useful when you're building a big ol' pile of role "building blocks" where a couple of them should absolutely never, ever be used together. π«
π Attributes
A role's attributes are like a class's attributes, except β plot twist β they don't actually get applied. So any method that an attribute accessor would normally generate? Not generated in the role. Nope. Those only get created once the role is actually applied to a class. Delayed gratification, main character energy. β¨
π Methods
These are the methods defined inside the role. Simple as that. No cap. π
π Required Methods
A role can require a consuming class (or role) to hand over a given method. If a class fails to do that, it's a fatal error. If it's a role that fails, it just passes the method requirement along to its consuming role. Chain of custody, bestie. π
π Required Attributes
Just like a role can require methods, it can also require attributes. And here's the rule: the attribute that fulfills the requirement must implement at least as much as is required. So for example β if the role says the attribute has to be read-only, then the fulfilling attribute must at least have a reader (it can also have a writer, that's fine). And if the role says the attribute has to be an ArrayRef, then it must be either an ArrayRef or a subtype of an ArrayRef. Meet the bar or go home. π«Ά
π Overridden Methods
The override and super keywords are allowed in roles, but their behavior is different from their class counterparts. In a class, super points directly at that class's superclass. In a role, super is deferred β it has no meaning until the role gets composed into a class. Once that composition happens, super then refers to that class's superclass. π¦
And this is key, so write it on your mirror: roles do not have hierarchy, so they can never have a super role. Periodt. π
π Method Modifiers
These are the before, around and after modifiers you know and love from Moose classes. The difference here? The modifiers are not actually applied until the role is composed into a class. (This is exactly like attributes and the override keyword β same energy.) π
π§ Role Composition
π Composing into a Class
Topics on deck:
- Excluded Roles
- Required Methods
- Required Attributes
- Attributes
- Methods
- Overridden methods
- Method Modifiers (before, around, after)
π Composing into a Instance
(no extra deets here, that's just the heading, moving on π)
π Composing into a Role
- Excluded Roles
- Required Methods
- Required Attributes
- Attributes
- Methods
- Overridden methods
- Method Modifiers (before, around, after)
π Role Summation
When multiple roles get added to another role (using the with @roles keyword), the roles are composed symmetrically. The product of that composition is a composite role β that's Moose::Meta::Role::Composite, bestie. β¨
π Excluded Roles
(no extra deets, just vibes)
π Required Methods
(no extra deets, just vibes)
π Required Attributes
(no extra deets, just vibes)
π Attributes
Attributes with the same name will conflict, and that's considered an unrecoverable error. Like, we don't even look at any other aspect of the attribute β if the names clash, that's already enough. Done. π
And why so harsh and so early? Because there's so much room for variance between two attributes that the problem explodes immediately and the rules get insanely complex. The author's opinion, stated right there in the spec: that complexity is not worth the trouble.
π Methods
Methods with the same name will conflict too β but no error gets thrown! Instead, the method name just gets added to the list of required methods for the new composite role. Chill conflict, honestly. π
Set theory time, because we're that girl: each role can be said to have a set of methods. The symmetric difference of the two sets becomes the new set of methods for the composite role, and the intersection of the two sets is the conflicts. Illustrated like so:
Role A has method set { a, b, c }
Role B has method set { c, d, e }
The composite role (A,B) has
method set { a, b, d, e }
conflict set { c }
π Overridden methods
An overridden method can conflict in one of two ways.
- First way: it clashes with another overridden method of the same name. That's an unrecoverable error β and it's an obvious one, because you literally cannot override a method twice in the same class. π
- Second way: an overridden method and a regular method share a name. Also an unrecoverable error, because there's no way to combine the two, and it's not okay for both of them to end up composed into a single class at some point.
Using override in roles can be tricky β but if you use it carefully, it can be a very powerful tool. π
π Method Modifiers (before, around, after)
Method modifiers are the only place where the ordering of role composition matters. That's just the nature of method modifiers themselves. π¦
Since a method can have multiple method modifiers, they're simply collected in order, so they can later be applied to the class in that same order.
In general, great care should be taken when using method modifiers in roles. That order sensitivity can totally lead to subtle, hard-to-find bugs if you overuse them. As with all good things in life, moderation is the key. π₯
π Composition Edge Cases
This is just a little collection of complex edge cases that are easy to get confused about. It tries to clarify those cases and explain what's actually going on in them.
β Role Method Overriding
So many people want to "override" methods in the roles they're consuming. That works great for classes β the local class method gets favored over the role method. But in roles it's trickier, because conflicts mean neither method is chosen and the method gets "required" instead. π
Here's an example of that (incorrect) type of overriding:
package Role::Foo;
use Moose::Role;
sub foo { ... }
package Role::FooBar;
use Moose::Role;
with 'Role::Foo';
sub foo { ... }
sub bar { ... }
Here the foo methods conflict, and Role::FooBar now requires any class or role consuming it to implement foo. Which is very often not what the user wanted. π
Now here's an example of the (correct) type of overriding β except it's not overriding at all, as the text below explains:
package Role::Foo;
use Moose::Role;
sub foo { ... }
package Role::Bar;
use Moose::Role;
sub foo { ... }
sub bar { ... }
package Role::FooBar;
use Moose::Role;
with 'Role::Foo', 'Role::Bar';
sub foo { ... }
This works because the combination of Role::Foo and Role::Bar produces a conflict on the foo method. That conflict means the composite role (created by combining Role::Foo and Role::Bar using the with keyword) has a method requirement of foo. And then Role::FooBar fulfills that requirement. β¨
It's important to note: Role::FooBar is simply fulfilling the required foo method, and NOT overriding foo. That distinction is important, bestie. Write it down. π
And now another example of a (correct) type of overriding, this time using the excludes option:
package Role::Foo;
use Moose::Role;
sub foo { ... }
package Role::FooBar;
use Moose::Role;
with 'Role::Foo' => { -excludes => 'foo' };
sub foo { ... }
sub bar { ... }
By specifically excluding the foo method during composition, we let Role::FooBar define its own version of foo. Slay. π
π¦ SEE ALSO π¦
Traits
Roles are based on Traits, which originated over in the Smalltalk community.
<http://www.iam.unibe.ch/~scg/Research/Traits/>β This is the main site for the original Traits papers. π- Class::Trait β I created this implementation of traits several years ago, after reading the papers linked above. (This module is now maintained by Ovid and I am no longer involved with it.)
Roles
Since roles are relatively new, and the Moose implementation is probably the most mature one out there, there isn't much to link to. But here are some bits worth looking at (mostly Perl 6 related):
<http://www.oreillynet.com/onlamp/blog/2006/08/roles_composable_units_of_obje.html>β This is chromatic's take on roles, worth reading since he was/is one of the big proponents of them. π<http://svn.perl.org/perl6/doc/trunk/design/syn/S12.pod>β This is Synopsis 12, which is all about the Perl 6 Object System. Which, of course, includes roles. β
π AUTHORS π
- 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 thing bestie π«Ά this was perl v5.42.0, dated 2025-07-25, served to you fresh as Moose::Spec::Role(3) β go forth and compose your roles responsibly πβ¨
π¦ 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