X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FManual%2FRoles.pod;h=9ad655668b2ab9a52f1f59cc680a1337b4698ad1;hb=f9b1ab71234d11a9121de96c574ca980bbfb3eaa;hp=3e7397fff3640a19a43f9f43fd31e442ea7d01a4;hpb=2840a3b25fac3ab606e2053ce9ef30b39687270d;p=gitmo%2FMoose.git diff --git a/lib/Moose/Manual/Roles.pod b/lib/Moose/Manual/Roles.pod index 3e7397f..9ad6556 100644 --- a/lib/Moose/Manual/Roles.pod +++ b/lib/Moose/Manual/Roles.pod @@ -2,20 +2,22 @@ =head1 NAME -Moose::Manual::Roles - Roles, an Alternative to Deep Hierarchies and Base Classes +Moose::Manual::Roles - Roles, an alternative to deep hierarchies and base classes =head1 WHAT IS A ROLE? 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. +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 show up in the -class as if they were defined directly in the class. +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. 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. @@ -46,7 +48,7 @@ Creating a role looks a lot like creating a Moose class: $self->is_broken(1); } -Except for our use of C, this looks just like a class +Except for our use of L, this looks just like a class definition with Moose. However, this is not a class, and it cannot be instantiated. @@ -122,18 +124,14 @@ methods: If we try to consume this role in a class that does not have a C method, we will get an exception. -Note that attribute-generated accessors do not satisfy the requirement -that the named method exists. Similarly, a method modifier does not -satisfy this requirement either. This may change in the future. - -You can also see that we added a method modifier on -C. Basically, we want consuming classes to implement their own -logic for breaking, but we make sure that the C attribute -is always set to true when C is called. +You can see that we added a method modifier on C. We want +classes that consume this role to implement their own logic for +breaking, but we make sure that the C attribute is always +set to true when C is called. package Car - use Moose; + use Moose; with 'Breakable'; @@ -150,6 +148,24 @@ is always 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 a "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 @@ -180,7 +196,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 @@ -234,6 +250,21 @@ C and C, but does not provide a C method. If some API expects an object that does one of those roles, it probably expects it to implement that method. +In some use cases we might alias and exclude methods from roles, but +then provide a method of the same name in the class itself. + +=head1 ROLE EXCLUSION + +A role can say that it cannot be combined with some other role. This +should be used with great caution, since it limits the re-usability of +the role. + + package Breakable; + + use Moose::Role; + + excludes 'BreakDancer'; + =head1 AUTHOR Dave Rolsky Eautarch@urth.orgE