NAME
Role - A simple role system for Perl
VERSION
Version v0.1.1
SYNOPSIS
Creating Roles
package Role::Printable;
use Role;
requires 'to_string'; # Classes must implement this
sub print {
my $self = shift;
print $self->to_string . "\n";
}
1;
package Role::Serialisable;
use Role;
requires 'serialize', 'deserialize';
sub to_json {
my $self = shift;
# ... implementation
}
1;
Using Roles in Classes
package My::Class;
use Class;
with qw/Role::Printable Role::Serialisable/;
sub to_string {
my $self = shift;
return "My::Class instance";
}
sub serialize { ... }
sub deserialize { ... }
1;
Applying Roles at Runtime
package My::Class;
use Class;
# Later, apply roles dynamically
Role::apply_role(__PACKAGE__, 'Role::Printable');
1;
Role Aliasing
package My::Class;
use Class;
use Role::Printable => {
role => 'Role::Printable',
alias => { print => 'display' }
};
# Now use $obj->display() instead of $obj->print()
Role Composition with Exclusions
package Role::A;
use Role;
excludes 'Role::B'; # Cannot be used with Role::B
package Role::B;
use Role;
package My::Class;
use Class;
use Role::A; # OK
# use Role::B; # This would die
DESCRIPTION
Role provides a simple, efficient role system for Perl. Roles are reusable units of behavior that can be composed into classes. They support requirements, method conflicts detection, aliasing, and runtime application.
This module is designed to work with any class system but integrates particularly well with Class::More.
FEATURES
Core Features
Method Requirements: Roles can declare methods that consuming classes must implement
Conflict Detection: Automatic detection of method conflicts between roles
Method Aliasing: Rename methods when applying roles to avoid conflicts
Role Exclusion: Roles can declare incompatible roles
Runtime Application: Apply roles to classes at runtime
Basic Attribute Support: Simple attribute storage with accessors
Performance Optimized: Method and role caching for better performance
Class Method Priority: Class methods silently override role methods
Advanced Features
Batch Conflict Detection: Detects conflicts between multiple roles before application
Sequential Application: Supports applying roles one at a time with proper conflict checking
Inheritance Awareness: Understands method inheritance chains
Role Composition Tracking: Tracks which roles are applied to each class
METHODS
Role Definition Methods
These methods are available in packages that use Role.
requires
requires 'method1', 'method2';
Declares that consuming classes must implement the specified methods.
excludes
excludes 'Role::Incompatible', 'Role::Conflicting';
Declares that this role cannot be composed with the specified roles.
has
has 'attribute_name';
has 'attribute_name' => ( default => 'value' );
Defines a simple attribute in the role. Creates a basic accessor method. The attribute specification can include:
default- Default value for the attribute
Note: This provides basic attribute storage. For advanced attribute features like type constraints, coercion, or lazy building, use a full-featured class system.
Role Application Methods
with
package My::Class;
use Class;
with 'Role::A', 'Role::B';
# With aliasing
with
{ role => 'Role::A', alias => { method_a => 'new_name' } },
'Role::B';
Composes roles into a class. Can be called as a class method.
apply_role
Role::apply_role('My::Class', 'Role::Printable');
Role::apply_role($object, 'Role::Serialisable');
Applies a role to a class or object at runtime. Returns true on success.
Query Methods
does
if ($object->does('Role::Printable')) {
$object->print;
}
Checks if a class or object consumes a specific role.
get_applied_roles
my @roles = Role::get_applied_roles('My::Class');
my @roles = Role::get_applied_roles($object);
Returns the list of roles applied to a class.
is_role
if (Role::is_role('Role::Printable')) {
# It's a role
}
Checks if a package is a role.
EXAMPLES
Basic Role with Requirements
package Role::Validator;
use Role;
requires 'validate', 'get_errors';
sub is_valid {
my $self = shift;
return $self->validate && !@{$self->get_errors};
}
1;
Role with Simple Attributes
package Role::Timestamped;
use Role;
has 'created_at' => ( default => sub { time } );
has 'updated_at' => ( default => sub { time } );
sub update_timestamp {
my $self = shift;
$self->updated_at(time);
}
1;
# Usage in class:
package My::Class;
use Class;
with qw/Role::Timestamped/;
sub new {
my ($class, %args) = @_;
my $self = bless \%args, $class;
$self->created_at(time) unless $self->created_at;
return $self;
}
1;
Role with Aliasing
package My::Class;
use Class;
# Avoid conflict by aliasing
with
{ role => 'Role::Logger', alias => { log => 'file_log' } },
{ role => 'Role::Debug', alias => { log => 'debug_log' } };
sub log {
my ($self, $message) = @_;
$self->file_log($message);
$self->debug_log($message);
}
1;
Runtime Role Application
package PluginSystem;
use Role;
sub load_plugin {
my ($self, $plugin_role) = @_;
unless (Role::is_role($plugin_role)) {
die "$plugin_role is not a role";
}
# Apply the plugin role to this instance's class
Role::apply_role($self, $plugin_role);
return $self;
}
1;
ATTRIBUTE SUPPORT
The has method in roles provides basic attribute functionality:
Creates a simple accessor method
Supports default values
Stores data in the object hash
However, this is basic attribute support. For advanced attribute features like:
Read-only/read-write access control
Type constraints
Lazy evaluation
Triggers and coercion
Initialisation hooks
You should use a full-featured class system like Moose, Moo, or Object::Pad and apply roles from those systems instead.
PERFORMANCE
The module includes several performance optimisations:
Method origin caching to avoid repeated lookups
Role loading caching to prevent redundant requires
Precomputed role method lists
Skip patterns for common non-method symbols
For best performance, apply roles at compile time when possible.
LIMITATIONS
Known Limitations
Basic Attribute Support:
Only simple attributes with default values are supported. No advanced features like read-only, type constraints, or lazy building.Inheritance Complexity:
Deep inheritance hierarchies may have unexpected method resolution behavior.Sequential Application:
Applying roles sequentially vs. batched can produce different conflict detection results.Method Modification:
Does not support method modifiers (before, after, around) like Moose roles.Role Parameters:
Roles cannot take parameters at composition time.Diamond Problem:
Limited handling of diamond inheritance patterns in role composition.Meta Information:
No rich meta-object protocol for introspection.
Attribute Limitations
The attribute system is intentionally minimal:
# Supported:
has 'name';
has 'count' => ( default => 0 );
has 'items' => ( default => sub { [] } );
# NOT supported:
has 'name' => ( is => 'ro' ); # No access control
has 'count' => ( isa => 'Int' ); # No type constraints
has 'items' => ( lazy => 1 ); # No lazy building
has 'score' => ( trigger => \&_validate_score ); # No triggers
Conflict Resolution Limitations
Class methods always silently win over role methods
No built-in way to explicitly override role methods
No method selection or combination features
Aliasing is the primary conflict resolution mechanism
Compatibility Limitations
Designed to work with simple class systems and Class::More
May have issues with some class builders that don't follow standard Perl OO
No Moose/Mouse compatibility layer
Limited support for role versioning
DIAGNOSTICS
Common Errors
"Failed to load role 'Role::Name': ..."The specified role could not be loaded. Make sure the role package exists and uses
use Role;."Conflict: method 'method_name' provided by both 'Role::A' and 'Role::B'..."Method conflict detected. Use aliasing or role exclusion to resolve.
"Role 'Role::Name' requires method(s) that are missing..."The class doesn't implement all required methods specified by the role.
"Role 'Role::A' cannot be composed with role(s): Role::B"Role exclusion violation.
"ROLE WARNING: Role 'Role::Name' has attributes that will be ignored"Role defines attributes but the class doesn't support attribute handling.
SEE ALSO
Class::More - Simple class builder that works well with Role
Moose::Role - Full-featured role system for Moose
Mouse::Role - Lightweight Moose-compatible roles
Role::Tiny - Minimalist role system
Moo::Role - Roles for Moo classes
AUTHOR
Mohammad Sajid Anwar, <mohammad.anwar at yahoo.com>
REPOSITORY
https://github.com/manwar/Class-Mite
BUGS
Please report any bugs or feature requests through the web interface at https://github.com/manwar/Class-Mite/issues. I will be notified and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Role
You can also look for information at:
BUG Report
LICENSE AND COPYRIGHT
Copyright (C) 2025 Mohammad Sajid Anwar.
This program is free software; you can redistribute it and / or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at:
http://www.perlfoundation.org/artistic_license_2_0
Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.
If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.
This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.
This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.
Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.