View on
MetaCPAN is shutting down
For details read Perl NOC. After June 25th this page will redirect to
chromatic > Class-Roles > Class::Roles



Annotate this POD


Open  1
View/Report Bugs
Module Version: 0.30   Source  


Class::Roles - use Perl 6 roles in Perl 5


    # provide a role
    package Animal;

    use Class::Roles role => [qw( eat sleep )]

    sub eat   { 'chomp chomp' }; 
    sub sleep { 'snore snore' };

    # use a role
    package Dog;

    use Class::Roles does => 'Animal';

    # test that a class or object performs a role
    $dog->does( 'Animal' );
    Dog->does( 'Animal' );
    UNIVERSAL::does( 'Dog', 'Animal' );

    # test that subclasses also respect their parents' roles

    package RoboDog;

    use base 'Dog';

    Dog->does( 'Animal' );


Class::Roles provides a Perl 5 implementation of Perl 6 roles.

Roles are named collections of reusable behavior. They provide a mechanism to mark that a class performs certain behaviors and to reuse the code that performs those behaviors.

Polymorphism is a fundamental feature of object orientation. It's important that behaviors that are similar in a semantic sense but different in specific details can be abstracted behind the same name. A dog may sleep by turning in circles three times then lying down while a cat may sprawl out across the nearest human lap. Both sleep, however.

Allomorphism -- polymorphic equivalence -- is a lesser-known feature. This suggests that objects with compatible behavior should be able to be treated interchangeably. A Dog and a Lifeguard may both understand the rescue_drowning_swimmer message, not because they share a common ancestor class but because they share a role.


Defining a Role

To define a role, define a package containing the methods that comprise that role. Pass these methods to Class::Roles' import() method via the role keyword. For example, the Lifeguard role may be:

    package Lifeguard;

    use Class::Roles role => 'rescue_drowning_swimmer', 'scan_ocean';

    sub rescue_drowning_swimmer
        # implementation here

    sub scan_ocean
        # implementation here

A Lifeguard role will be declared, comprised of the rescue_drowning_swimmer and scan_ocean methods.

Defining Multiple Roles in a Module

Use the multi target to define multiple roles in a single module:

    package MultiRoles;

    sub drive_around   { ... }
    sub steering_wheel { ... }

    sub fly_around     { ... }
    sub yoke           { ... }

    use Class::Roles multi =>
        car   => [qw( drive_around steering_wheel )],
        plane => [qw( fly_around   yoke           )],

Performing a Role

Any class that performs a role should declare that it does so, via the does keyword to import():

    package Dog;

    use Class::Roles does => 'Lifeguard';

Any methods of the role that the performing class does not implement will be imported.

As you'd expect, extending a class that performs a role means that the subclass also performs that role. Inheritance is just a specific case of role-based systems.

A Word About Existing Methods

Due to the nature of Perl 5, you may see Subroutine foo redefined warnings if you mark a class as performing a role which already implements one or more methods of that role. You can solve this in several ways, in rough order of preference:

Testing a Role

Use the does() method to test that a class or object performs the named role.

    my $dog = Dog->new();

    print "Can't help a drowning swimmer\n"
        unless $dog->does( 'Lifeguard' );

Use does() instead of isa() if allomorphism is important to you.

Applying a Role to Another Class

You can apply a role to a class outside of the other class:

    use Mail::TempAddress;
    use Mail::Action::DeleteAddresses;

    use Class::Roles
        apply => {
            to   => 'Mail::TempAddress::Addresses',
            role => 'DeleteAddresses',

The usual caveats apply. In general, this should work on just about any other class. In specific, the implementation and nature of the role will have a great effect on the efficacy of this technique.



chromatic, <>


No known bugs.



Copyright (c) 2003, chromatic. All rights reserved. This module is distributed under the same terms as Perl itself, in the hope that it is useful but certainly under no guarantee.

syntax highlighting: