chromatic > Class-Roles-0.30 > Class::Roles

Download:
Class-Roles-0.30.tar.gz

Dependencies

Annotate this POD

CPAN RT

Open  0
Report a bug
Module Version: 0.30   Source  

NAME ^

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

SYNOPSIS ^

    # 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' );

DESCRIPTION ^

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.

USAGE ^

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.

SEE ALSO ^

AUTHOR ^

chromatic, <chromatic@wgz.org>

BUGS ^

No known bugs.

TODO ^

COPYRIGHT ^

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.