.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32 .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Class::Roles 3" .TH Class::Roles 3 "2008-01-07" "perl v5.8.8" "User Contributed Perl Documentation" .SH "NAME" Class::Roles \- use Perl 6 roles in Perl 5 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& # provide a role \& package Animal; .Ve .PP .Vb 1 \& use Class::Roles role => [qw( eat sleep )] .Ve .PP .Vb 2 \& sub eat { 'chomp chomp' }; \& sub sleep { 'snore snore' }; .Ve .PP .Vb 2 \& # use a role \& package Dog; .Ve .PP .Vb 1 \& use Class::Roles does => 'Animal'; .Ve .PP .Vb 4 \& # test that a class or object performs a role \& $dog->does( 'Animal' ); \& Dog->does( 'Animal' ); \& UNIVERSAL::does( 'Dog', 'Animal' ); .Ve .PP .Vb 1 \& # test that subclasses also respect their parents' roles .Ve .PP .Vb 1 \& package RoboDog; .Ve .PP .Vb 1 \& use base 'Dog'; .Ve .PP .Vb 1 \& Dog->does( 'Animal' ); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Class::Roles provides a Perl 5 implementation of Perl 6 roles. .PP 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. .PP 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. .PP Allomorphism \*(-- polymorphic equivalence \*(-- is a lesser-known feature. This suggests that objects with compatible behavior should be able to be treated interchangeably. A \f(CW\*(C`Dog\*(C'\fR and a \f(CW\*(C`Lifeguard\*(C'\fR may both understand the \&\f(CW\*(C`rescue_drowning_swimmer\*(C'\fR message, not because they share a common ancestor class but because they share a role. .SH "USAGE" .IX Header "USAGE" .Sh "Defining a Role" .IX Subsection "Defining a Role" To define a role, define a package containing the methods that comprise that role. Pass these methods to \f(CW\*(C`Class::Roles\*(C'\fR' \f(CW\*(C`import()\*(C'\fR method via the \&\f(CW\*(C`role\*(C'\fR keyword. For example, the \f(CW\*(C`Lifeguard\*(C'\fR role may be: .PP .Vb 1 \& package Lifeguard; .Ve .PP .Vb 1 \& use Class::Roles role => 'rescue_drowning_swimmer', 'scan_ocean'; .Ve .PP .Vb 4 \& sub rescue_drowning_swimmer \& { \& # implementation here \& } .Ve .PP .Vb 4 \& sub scan_ocean \& { \& # implementation here \& } .Ve .PP A \f(CW\*(C`Lifeguard\*(C'\fR role will be declared, comprised of the \&\f(CW\*(C`rescue_drowning_swimmer\*(C'\fR and \f(CW\*(C`scan_ocean\*(C'\fR methods. .Sh "Defining Multiple Roles in a Module" .IX Subsection "Defining Multiple Roles in a Module" Use the \f(CW\*(C`multi\*(C'\fR target to define multiple roles in a single module: .PP .Vb 1 \& package MultiRoles; .Ve .PP .Vb 2 \& sub drive_around { ... } \& sub steering_wheel { ... } .Ve .PP .Vb 2 \& sub fly_around { ... } \& sub yoke { ... } .Ve .PP .Vb 5 \& use Class::Roles multi => \& { \& car => [qw( drive_around steering_wheel )], \& plane => [qw( fly_around yoke )], \& } .Ve .Sh "Performing a Role" .IX Subsection "Performing a Role" Any class that performs a role should declare that it does so, via the \f(CW\*(C`does\*(C'\fR keyword to \f(CW\*(C`import()\*(C'\fR: .PP .Vb 1 \& package Dog; .Ve .PP .Vb 1 \& use Class::Roles does => 'Lifeguard'; .Ve .PP Any methods of the role that the performing class does not implement will be imported. .PP 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. .PP \fIA Word About Existing Methods\fR .IX Subsection "A Word About Existing Methods" .PP Due to the nature of Perl 5, you may see \f(CW\*(C`Subroutine foo redefined\*(C'\fR 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: .IP "* Predeclare all existing subs before you use Class::Roles:" 4 .IX Item "Predeclare all existing subs before you use Class::Roles:" .Vb 1 \& sub foo; .Ve .Sp .Vb 1 \& use Class::Roles does => 'Foo'; .Ve .ie n .IP "* Call ""Class::Roles::import()"" explicitly:" 4 .el .IP "* Call \f(CWClass::Roles::import()\fR explicitly:" 4 .IX Item "Call Class::Roles::import() explicitly:" .Vb 2 \& use Class::Roles; \& Class::Roles->import( does => 'Foo' ); .Ve .Sp .Vb 4 \& sub foo \& { \& ... \& } .Ve .IP "* Use Class::Roles after declaring the existing methods:" 4 .IX Item "Use Class::Roles after declaring the existing methods:" .Vb 4 \& sub foo \& { \& ... \& } .Ve .Sp .Vb 1 \& use Class::Roles does => 'Foo'; .Ve .ie n .IP "* Disable the ""redefined"" warning with the warnings pragma of 5.6 on" 4 .el .IP "* Disable the \f(CWredefined\fR warning with the warnings pragma of 5.6 on" 4 .IX Item "Disable the redefined warning with the warnings pragma of 5.6 on" .Vb 1 \& use Class::Roles does => 'Foo'; .Ve .Sp .Vb 1 \& no warnings 'redefine'; .Ve .Sh "Testing a Role" .IX Subsection "Testing a Role" Use the \f(CW\*(C`does()\*(C'\fR method to test that a class or object performs the named role. .PP .Vb 1 \& my $dog = Dog->new(); .Ve .PP .Vb 2 \& print "Can't help a drowning swimmer\en" \& unless $dog->does( 'Lifeguard' ); .Ve .PP Use \f(CW\*(C`does()\*(C'\fR instead of \f(CW\*(C`isa()\*(C'\fR if allomorphism is important to you. .Sh "Applying a Role to Another Class" .IX Subsection "Applying a Role to Another Class" You can apply a role to a class outside of the other class: .PP .Vb 2 \& use Mail::TempAddress; \& use Mail::Action::DeleteAddresses; .Ve .PP .Vb 5 \& use Class::Roles \& apply => { \& to => 'Mail::TempAddress::Addresses', \& role => 'DeleteAddresses', \& }; .Ve .PP 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. .SH "SEE ALSO" .IX Header "SEE ALSO" .IP "* Class::ActsLike, a less P6\-ish approach" 4 .IX Item "Class::ActsLike, a less P6-ish approach" .PD 0 .IP "* Traits: Composable Units of Behavior" 4 .IX Item "Traits: Composable Units of Behavior" .PD .IP "* Allomorphism at the Portland Pattern Repository" 4 .IX Item "Allomorphism at the Portland Pattern Repository" .SH "AUTHOR" .IX Header "AUTHOR" chromatic, .SH "BUGS" .IX Header "BUGS" No known bugs. .SH "TODO" .IX Header "TODO" .IP "* merge with Class::Role (soon)" 4 .IX Item "merge with Class::Role (soon)" .PD 0 .IP "* better error checking (some in this version, some later)" 4 .IX Item "better error checking (some in this version, some later)" .IP "* keep up to date with Perl 6 syntax (long\-term goals)" 4 .IX Item "keep up to date with Perl 6 syntax (long-term goals)" .PD .SH "COPYRIGHT" .IX Header "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.