X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FManual%2FRoles.pod;h=938f348d8d33bb3f9e06704bc509e0a14dcf27a6;hb=50f346d77d9505cae6370603be0ab51fe3298aa2;hp=73b08df5ef788d0194bd164f64c15c67145f94eb;hpb=d67ce58f8d57e240ded1f1ebdf262456ce2ff5be;p=gitmo%2FMoose.git diff --git a/lib/Moose/Manual/Roles.pod b/lib/Moose/Manual/Roles.pod index 73b08df..938f348 100644 --- a/lib/Moose/Manual/Roles.pod +++ b/lib/Moose/Manual/Roles.pod @@ -8,15 +8,16 @@ Moose::Manual::Roles - Roles, an alternative to deep hierarchies and base classe A role is something that classes do. Usually, a role encapsulates some piece of behavior or state that can be shared between classes. It is -important to understand that I. Roles do not -participate in inheritance, and a role cannot be instantiated. We -sometimes say that classes I roles. +important to understand that I. You cannot +inherit from a role, and a role cannot be instantiated. We sometimes +say that roles are I, either by classes or other roles. Instead, a role is I into a class. In practical terms, this means that all of the methods and attributes defined in a role are added directly to (we sometimes say "flattened into") the class that consumes the role. These attributes and methods then appear as if they -were defined in the class itself. +were defined in the class itself. A subclass of the consuming class +will inherit all of these methods and attributes. Moose roles are similar to mixins or interfaces in other languages. @@ -26,6 +27,9 @@ own. You could have a role that consisted only of a list of required methods, in which case the role would be very much like a Java interface. +Note that attribute accessors also count as methods for the +purposes of satisfying the requirements of a role. + =head1 A SIMPLE ROLE Creating a role looks a lot like creating a Moose class: @@ -147,6 +151,24 @@ set to true when C is called. } } +=head2 Roles Versus Abstract Base Classes + +If you are familiar with the concept of abstract base classes in other +languages, you may be tempted to use roles in the same way. + +You I define an "interface-only" role, one that contains I +a list of required methods. + +However, any class which consumes this role must implement all of the +required methods, either directly or through inheritance from a +parent. You cannot delay the method requirement check so that they can +be implemented by future subclasses. + +Because the role defines the required methods directly, adding a base +class to the mix would not achieve anything. We recommend that you +simply consume the interface role in each class which implements that +interface. + =head1 USING METHOD MODIFIERS Method modifiers and roles are a very powerful combination. Often, a @@ -177,7 +199,7 @@ If a class composes multiple roles, and those roles have methods of the same name, we will have a conflict. In that case, the composing class is required to provide its I method of the same name. - package Breakdances; + package Breakdancer; use Moose::Role @@ -205,22 +227,22 @@ from both its roles, we can alias the methods: use Moose; - with 'Breakable' => { alias => { break => 'break_bone' } }, - 'Breakdancer' => { alias => { break => 'break_dance' } }; + with 'Breakable' => { -alias => { break => 'break_bone' } }, + 'Breakdancer' => { -alias => { break => 'break_dance' } }; However, aliasing a method simply makes a I of the method with the new name. We also need to exclude the original name: with 'Breakable' => { - alias => { break => 'break_bone' }, - exclude => 'break', + -alias => { break => 'break_bone' }, + -excludes => 'break', }, 'Breakdancer' => { - alias => { break => 'break_dance' }, - exclude => 'break', + -alias => { break => 'break_dance' }, + -excludes => 'break', }; -The exclude parameter prevents the C method from being composed +The excludes parameter prevents the C method from being composed into the C class, so we don't have a conflict. This means that C does not need to implement its own C method.