[Moose-commits] r7415 - Moose/branches/moose-manual/lib/Moose/Manual

autarch at code2.0beta.co.uk autarch at code2.0beta.co.uk
Thu Jan 29 18:05:38 GMT 2009


Author: autarch
Date: 2009-01-29 10:05:38 -0800 (Thu, 29 Jan 2009)
New Revision: 7415

Added:
   Moose/branches/moose-manual/lib/Moose/Manual/MethodModifiers.pod
   Moose/branches/moose-manual/lib/Moose/Manual/Roles.pod
Removed:
   Moose/branches/moose-manual/lib/Moose/Manual/MethodModifiers.pm
   Moose/branches/moose-manual/lib/Moose/Manual/Roles.pm
Log:
s/.pm/.pod/g

Deleted: Moose/branches/moose-manual/lib/Moose/Manual/MethodModifiers.pm
===================================================================
--- Moose/branches/moose-manual/lib/Moose/Manual/MethodModifiers.pm	2009-01-29 18:05:14 UTC (rev 7414)
+++ Moose/branches/moose-manual/lib/Moose/Manual/MethodModifiers.pm	2009-01-29 18:05:38 UTC (rev 7415)
@@ -1,273 +0,0 @@
-=pod
-
-=head1 NAME
-
-Moose::Manual::Attribute - Moose's Method Modifiers
-
-=head1 WHAT IS A METHOD MODIFIER?
-
-Moose provides a feature called "method modifiers". Another word for
-this feature might be "hooks" or "advice".
-
-It's probably easiest to understand this feature with a few examples:
-
-  package Example;
-
-  use Moose;
-
-  sub foo {
-      print "foo\n";
-  }
-
-  before 'foo' => sub { print "about to call foo\n"; };
-  after 'foo'  => sub { print "just called foo\n"; };
-
-  around 'foo' => sub {
-      my $orig = shift;
-      my $self = shift;
-
-      print "I'm around foo\n";
-
-      $self->$orig(@_);
-
-      print "I'm still around foo\n";
-  };
-
-Now if I call C<< Example->new->foo >> I'll get the following output:
-
-  about to call foo
-  I'm around foo
-  foo
-  I'm still around foo
-  just called foo
-
-You probably could have figured that out from the names "before",
-"after", and "around".
-
-Also, as you can see, the before modifiers come before around
-modifiers, and after modifiers come last.
-
-When there are multiple modifiers of the same type, the before and
-around modifiers run from the last added to the first, and after
-modifiers run from first added to last:
-
-   before 2
-    before 1
-     around 2
-      around 1
-       primary
-      around 1
-     around 2
-    after 1
-   after 2
-
-=head1 WHY USE THEM?
-
-Method modifiers have many uses. One very common use is in roles. This
-lets roles alter the behavior of methods in the classes that use
-them. See L<Moose::Manual::Roles> for more about roles.
-
-Modifiers really are at their most useful in roles, so some of the
-examples below are a bit artificial. They're intended to give you an
-idea of how modifiers work, but may not be the most natural usages.
-
-=head1 BEFORE, AFTER, AND AROUND
-
-Method modifiers can also be used to add behavior to a method that
-Moose generates for you, such as an attribute accessor:
-
-  has 'size' => ( is => 'rw' );
-
-  before 'size' => sub {
-      my $self = shift;
-
-      if (@_) {
-          Carp::cluck('Someone is setting size');
-      }
-  };
-
-Another use for the before modifier would be to do some sort of
-pre-checking on a method call. For example:
-
-  before 'size' => sub {
-      my $self = shift;
-
-      die 'Cannot set size while the person is growing'
-          if @_ && $self->is_growing;
-  };
-
-This lets us implement logical checks that don't fit well into
-constraints.
-
-Similarly, an after modifier could be used for logging an action that
-was taken.
-
-Note that the return values of both before and after modifiers are
-ignored.
-
-An around modifier is a bit more powerful than either a before or
-after modifier. First, it is easy to modify the arguments being passed
-onto the original method in an around modifier. Second, you can decide
-to simply not call the original method at all, unlike with other
-modifiers. Finally, you can modify the return value with an around
-modifier.
-
-An around modifier receives the original method as its first argument,
-I<then> the object, and finally any arguments passed to the method.
-
-  around 'size' => sub {
-      my $orig = shift;
-      my $self = shift;
-
-      return $self->$orig()
-          unless @_;
-
-      my $size = shift;
-      $size = $size / 2
-          if $self->likes_small_things();
-
-      return $self->$orig($size);
-  };
-
-=head1 INNER AND AUGMENT
-
-Augment and inner are two halves of the same feature. The augment
-modifier provides a sort of inverted subclassing. You provide part of
-the implementation in a superclass, and then document that subclasses
-are expected to provide the rest.
-
-The superclass calls C<inner()>, which then calls the C<augment>
-modifier in the subclass:
-
-  package Document;
-
-  use Moose;
-
-  sub as_xml {
-      my $self = shift;
-
-      my $xml = "<document>\n";
-      $xml .= inner();
-      $xml .= "</document>\n";
-
-      return $xml;
-  }
-
-Using C<inner()> in this method makes it possible for one or more
-subclasses to then augment this method with their own specific
-implementation:
-
-  package Report;
-
-  use Moose;
-
-  extends 'Document';
-
-  augment 'as_xml' => sub {
-      my $self = shift;
-
-      my $xml = "<report>\n";
-      $xml .= inner();
-      $xml .= "</report>\n";
-
-      return $xml;
-  };
-
-When we call C<as_xml> on a Report object, we get something like this:
-
-  <document>
-  <report>
-  </report>
-  </document>
-
-But we also called C<inner()> in C<Report>, so we can continue
-subclassing and adding more content inside the document:
-
-  package Report::IncomeAndExpenses;
-
-  use Moose;
-
-  extends 'Report';
-
-  augment 'as_xml' => sub {
-      my $self = shift;
-
-      my $xml = '<income>' . $self->income . '</income>';
-      $xml .= "\n";
-      my $xml = '<expenses>' . $self->expenses . '</expenses>';
-      $xml .= "\n";
-
-      $xml .= inner() || q{};
-
-      return $xml;
-  };
-
-Now our report has some content:
-
-  <document>
-  <report>
-  <income>$10</income>
-  <expenses>$8</expenses>
-  </report>
-  </document>
-
-What makes this combination of C<augment> and C<inner()> special is
-that it allows us to have methods which are called from I<parent
-(least specific) to child (most specific). This inverts the normal
-order, where the child's method is called first, and it in turn will
-call C<< $self->SUPER::method >> to call the parent.
-
-Note that in C<Report::IncomeAndExpenses> we call C<inner()> again. If
-the object is an instance of C<Report::IncomeAndExpenses> then this
-call is a no-op, and just returns false.
-
-=head1 OVERRIDE AND SUPER
-
-Finally, Moose provides some simple sugar for Perl's built-in method
-overriding scheme. If you want to override a method from a parent
-class, you can do this with C<override>:
-
-  package Employee;
-
-  use Moose;
-
-  extends 'Person';
-
-  has 'job_title' => ( is => 'rw' );
-
-  override 'display_name' => sub {
-      my $self = shift;
-
-      return super() . q{, } . $self->title();
-  };
-
-The call to C<super()> is almost the same as calling C<<
-$self->SUPER::display_name >>. The difference is that the arguments
-passed to the superclass's method will always be the same as the ones
-passed to the method modifier, and cannot be changed.
-
-All arguments passed to C<super()> are ignored, as are any changes
-made to C<@_> before C<super()> is called.
-
-=head1 SEMI-COLONS
-
-Because all of these method modifiers are implemented as Perl
-functions, you must always end the modifier declaration with a
-semi-colon:
-
-  after 'foo' => sub { };
-
-=head1 AUTHOR
-
-Dave Rolsky E<lt>autarch at urth.orgE<gt>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2008 by Infinity Interactive, Inc.
-
-L<http://www.iinteractive.com>
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut

Copied: Moose/branches/moose-manual/lib/Moose/Manual/MethodModifiers.pod (from rev 7175, Moose/branches/moose-manual/lib/Moose/Manual/MethodModifiers.pm)
===================================================================
--- Moose/branches/moose-manual/lib/Moose/Manual/MethodModifiers.pod	                        (rev 0)
+++ Moose/branches/moose-manual/lib/Moose/Manual/MethodModifiers.pod	2009-01-29 18:05:38 UTC (rev 7415)
@@ -0,0 +1,273 @@
+=pod
+
+=head1 NAME
+
+Moose::Manual::Attribute - Moose's Method Modifiers
+
+=head1 WHAT IS A METHOD MODIFIER?
+
+Moose provides a feature called "method modifiers". Another word for
+this feature might be "hooks" or "advice".
+
+It's probably easiest to understand this feature with a few examples:
+
+  package Example;
+
+  use Moose;
+
+  sub foo {
+      print "foo\n";
+  }
+
+  before 'foo' => sub { print "about to call foo\n"; };
+  after 'foo'  => sub { print "just called foo\n"; };
+
+  around 'foo' => sub {
+      my $orig = shift;
+      my $self = shift;
+
+      print "I'm around foo\n";
+
+      $self->$orig(@_);
+
+      print "I'm still around foo\n";
+  };
+
+Now if I call C<< Example->new->foo >> I'll get the following output:
+
+  about to call foo
+  I'm around foo
+  foo
+  I'm still around foo
+  just called foo
+
+You probably could have figured that out from the names "before",
+"after", and "around".
+
+Also, as you can see, the before modifiers come before around
+modifiers, and after modifiers come last.
+
+When there are multiple modifiers of the same type, the before and
+around modifiers run from the last added to the first, and after
+modifiers run from first added to last:
+
+   before 2
+    before 1
+     around 2
+      around 1
+       primary
+      around 1
+     around 2
+    after 1
+   after 2
+
+=head1 WHY USE THEM?
+
+Method modifiers have many uses. One very common use is in roles. This
+lets roles alter the behavior of methods in the classes that use
+them. See L<Moose::Manual::Roles> for more about roles.
+
+Modifiers really are at their most useful in roles, so some of the
+examples below are a bit artificial. They're intended to give you an
+idea of how modifiers work, but may not be the most natural usages.
+
+=head1 BEFORE, AFTER, AND AROUND
+
+Method modifiers can also be used to add behavior to a method that
+Moose generates for you, such as an attribute accessor:
+
+  has 'size' => ( is => 'rw' );
+
+  before 'size' => sub {
+      my $self = shift;
+
+      if (@_) {
+          Carp::cluck('Someone is setting size');
+      }
+  };
+
+Another use for the before modifier would be to do some sort of
+pre-checking on a method call. For example:
+
+  before 'size' => sub {
+      my $self = shift;
+
+      die 'Cannot set size while the person is growing'
+          if @_ && $self->is_growing;
+  };
+
+This lets us implement logical checks that don't fit well into
+constraints.
+
+Similarly, an after modifier could be used for logging an action that
+was taken.
+
+Note that the return values of both before and after modifiers are
+ignored.
+
+An around modifier is a bit more powerful than either a before or
+after modifier. First, it is easy to modify the arguments being passed
+onto the original method in an around modifier. Second, you can decide
+to simply not call the original method at all, unlike with other
+modifiers. Finally, you can modify the return value with an around
+modifier.
+
+An around modifier receives the original method as its first argument,
+I<then> the object, and finally any arguments passed to the method.
+
+  around 'size' => sub {
+      my $orig = shift;
+      my $self = shift;
+
+      return $self->$orig()
+          unless @_;
+
+      my $size = shift;
+      $size = $size / 2
+          if $self->likes_small_things();
+
+      return $self->$orig($size);
+  };
+
+=head1 INNER AND AUGMENT
+
+Augment and inner are two halves of the same feature. The augment
+modifier provides a sort of inverted subclassing. You provide part of
+the implementation in a superclass, and then document that subclasses
+are expected to provide the rest.
+
+The superclass calls C<inner()>, which then calls the C<augment>
+modifier in the subclass:
+
+  package Document;
+
+  use Moose;
+
+  sub as_xml {
+      my $self = shift;
+
+      my $xml = "<document>\n";
+      $xml .= inner();
+      $xml .= "</document>\n";
+
+      return $xml;
+  }
+
+Using C<inner()> in this method makes it possible for one or more
+subclasses to then augment this method with their own specific
+implementation:
+
+  package Report;
+
+  use Moose;
+
+  extends 'Document';
+
+  augment 'as_xml' => sub {
+      my $self = shift;
+
+      my $xml = "<report>\n";
+      $xml .= inner();
+      $xml .= "</report>\n";
+
+      return $xml;
+  };
+
+When we call C<as_xml> on a Report object, we get something like this:
+
+  <document>
+  <report>
+  </report>
+  </document>
+
+But we also called C<inner()> in C<Report>, so we can continue
+subclassing and adding more content inside the document:
+
+  package Report::IncomeAndExpenses;
+
+  use Moose;
+
+  extends 'Report';
+
+  augment 'as_xml' => sub {
+      my $self = shift;
+
+      my $xml = '<income>' . $self->income . '</income>';
+      $xml .= "\n";
+      my $xml = '<expenses>' . $self->expenses . '</expenses>';
+      $xml .= "\n";
+
+      $xml .= inner() || q{};
+
+      return $xml;
+  };
+
+Now our report has some content:
+
+  <document>
+  <report>
+  <income>$10</income>
+  <expenses>$8</expenses>
+  </report>
+  </document>
+
+What makes this combination of C<augment> and C<inner()> special is
+that it allows us to have methods which are called from I<parent
+(least specific) to child (most specific). This inverts the normal
+order, where the child's method is called first, and it in turn will
+call C<< $self->SUPER::method >> to call the parent.
+
+Note that in C<Report::IncomeAndExpenses> we call C<inner()> again. If
+the object is an instance of C<Report::IncomeAndExpenses> then this
+call is a no-op, and just returns false.
+
+=head1 OVERRIDE AND SUPER
+
+Finally, Moose provides some simple sugar for Perl's built-in method
+overriding scheme. If you want to override a method from a parent
+class, you can do this with C<override>:
+
+  package Employee;
+
+  use Moose;
+
+  extends 'Person';
+
+  has 'job_title' => ( is => 'rw' );
+
+  override 'display_name' => sub {
+      my $self = shift;
+
+      return super() . q{, } . $self->title();
+  };
+
+The call to C<super()> is almost the same as calling C<<
+$self->SUPER::display_name >>. The difference is that the arguments
+passed to the superclass's method will always be the same as the ones
+passed to the method modifier, and cannot be changed.
+
+All arguments passed to C<super()> are ignored, as are any changes
+made to C<@_> before C<super()> is called.
+
+=head1 SEMI-COLONS
+
+Because all of these method modifiers are implemented as Perl
+functions, you must always end the modifier declaration with a
+semi-colon:
+
+  after 'foo' => sub { };
+
+=head1 AUTHOR
+
+Dave Rolsky E<lt>autarch at urth.orgE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2008 by Infinity Interactive, Inc.
+
+L<http://www.iinteractive.com>
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut

Deleted: Moose/branches/moose-manual/lib/Moose/Manual/Roles.pm
===================================================================
--- Moose/branches/moose-manual/lib/Moose/Manual/Roles.pm	2009-01-29 18:05:14 UTC (rev 7414)
+++ Moose/branches/moose-manual/lib/Moose/Manual/Roles.pm	2009-01-29 18:05:38 UTC (rev 7415)
@@ -1,250 +0,0 @@
-=pod
-
-=head1 NAME
-
-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 are not classes>. Roles do not
-participate in inheritance, and a role cannot be instantiated.
-
-Instead, a role is I<composed> 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.
-
-Moose roles are similar to mixins or interfaces in other languages.
-
-Besides defining their own methods and attributes, roles can also
-require that the consuming class define certain methods of its
-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.
-
-=head1 A SIMPLE ROLE
-
-Creating a role looks a lot like creating a Moose class:
-
-  package Breakable;
-
-  use Moose::Role;
-
-  has 'is_broken' => (
-      is  => 'rw',
-      isa => 'Bool',
-  );
-
-  sub break {
-      my $self = shift;
-
-      print "I broke\n";
-
-      $self->is_broken(1);
-  }
-
-Except for our use of C<Moose::Role>, this looks just like a class
-definition with Moose. However, this is not a class, and it cannot be
-instantiated.
-
-Instead, its attributes and methods will be composed into classes
-which use the role:
-
-  package Car;
-
-  use Moose;
-
-  with 'Breakable';
-
-  has 'engine' => (
-      is  => 'ro',
-      isa => 'Engine',
-  );
-
-The C<with> function composes roles into a class. Once that is done,
-the C<Car> class has an C<is_broken> attribute and a C<break>
-method. The C<Car> class also C<does('Breakable')>:
-
-  my $car = Car->new( engine => Engine->new );
-
-  print $car->is_broken ? 'Still working' : 'Busted';
-  $car->break;
-  print $car->is_broken ? 'Still working' : 'Busted';
-
-  $car->does('Breakable'); # true
-
-This prints:
-
-  Still working
-  I broke
-  Busted
-
-We could use this same role in a C<Bone> class:
-
-  package Bone;
-
-  use Moose;
-
-  with 'Breakable';
-
-  has 'marrow' => (
-      is  => 'ro',
-      isa => 'Marrow',
-  );
-
-=head1 REQUIRED METHODS
-
-As mentioned previously, a role can require that consuming classes
-provide one or more methods. Using our C<Breakable> example, let's
-make it require that consuming classes implement their own C<break>
-methods:
-
-  package Breakable;
-
-  use Moose::Role;
-
-  requires 'break';
-
-  has 'is_broken' => (
-      is  => 'rw',
-      isa => 'Bool',
-  );
-
-  after 'break' => sub {
-      my $self = shift;
-
-      $self->is_broken(1);
-  };
-
-If we try to consume this role in a class that does not have a
-C<break> 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<break>. Basically, we want consuming classes to implement their own
-logic for breaking, but we make sure that the C<is_broken> attribute
-is always set to true when C<break> is called.
-
-  package Car
-
-      use Moose;
-
-  with 'Breakable';
-
-  has 'engine' => (
-      is  => 'ro',
-      isa => 'Engine',
-  );
-
-  sub break {
-      my $self = shift;
-
-      if ( $self->is_moving ) {
-          $self->stop;
-      }
-  }
-
-=head1 USING METHOD MODIFIERS
-
-Method modifiers and roles are a very powerful combination.  Often, a
-role will combine method modifiers and required methods. We already
-saw one example with our C<Breakable> example.
-
-Method modifiers increase the complexity of roles, because they make
-the role application order relevant. If a class uses multiple roles,
-each of which modify the same method, those modifiers will be applied
-in the same order as the roles are used:
-
-  package MovieCar;
-
-  use Moose;
-
-  extends 'Car';
-
-  with 'Breakable', 'ExplodesOnBreakage';
-
-Assuming that the new C<ExplodesOnBreakage> method I<also> has an
-C<after> modifier on C<break>, the C<after> modifiers will run one
-after the other. The modifier from C<Breakable> will run first, then
-the one from C<ExplodesOnBreakage>.
-
-=head1 METHOD CONFLICTS
-
-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<own> method of the same name.
-
-  package Breakdances;
-
-  use Moose::Role
-
-  sub break {
-
-  }
-
-If we compose both C<Breakable> and C<Breakdancer> in a class, we must
-provide our own C<break> method:
-
-  package FragileDancer;
-
-  use Moose;
-
-  with 'Breakable', 'Breakdancer';
-
-  sub break { ... }
-
-=head1 METHOD EXCLUSION AND ALIASING
-
-If we want our C<FragileDancer> class to be able to call the methods
-from both its roles, we can alias the methods:
-
-  package FragileDancer;
-
-  use Moose;
-
-  with 'Breakable'   => { alias => { break => 'break_bone' } },
-       'Breakdancer' => { alias => { break => 'break_dance' } };
-
-However, aliasing a method simply makes a I<copy> of the method with
-the new name. We also need to exclude the original name:
-
-  with 'Breakable' => {
-      alias   => { break => 'break_bone' },
-      exclude => 'break',
-      },
-      'Breakdancer' => {
-      alias   => { break => 'break_dance' },
-      exclude => 'break',
-      };
-
-The exclude parameter prevents the C<break> method from being composed
-into the C<FragileDancer> class, so we don't have a conflict. This
-means that C<FragileDancer> does not need to implement its own
-C<break> method.
-
-This is useful, but it's worth noting that this breaks the contract
-implicit in consuming a role. Our C<FragileDancer> class does both the
-C<Breakable> and C<BreakDancer>, but does not provide a C<break>
-method. If some API expects an object that does one of those roles, it
-probably expects it to implement that method.
-
-=head1 AUTHOR
-
-Dave Rolsky E<lt>autarch at urth.orgE<gt>
-
-=head1 COPYRIGHT AND LICENSE
-
-Copyright 2008 by Infinity Interactive, Inc.
-
-L<http://www.iinteractive.com>
-
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut

Copied: Moose/branches/moose-manual/lib/Moose/Manual/Roles.pod (from rev 7385, Moose/branches/moose-manual/lib/Moose/Manual/Roles.pm)
===================================================================
--- Moose/branches/moose-manual/lib/Moose/Manual/Roles.pod	                        (rev 0)
+++ Moose/branches/moose-manual/lib/Moose/Manual/Roles.pod	2009-01-29 18:05:38 UTC (rev 7415)
@@ -0,0 +1,250 @@
+=pod
+
+=head1 NAME
+
+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 are not classes>. Roles do not
+participate in inheritance, and a role cannot be instantiated.
+
+Instead, a role is I<composed> 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.
+
+Moose roles are similar to mixins or interfaces in other languages.
+
+Besides defining their own methods and attributes, roles can also
+require that the consuming class define certain methods of its
+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.
+
+=head1 A SIMPLE ROLE
+
+Creating a role looks a lot like creating a Moose class:
+
+  package Breakable;
+
+  use Moose::Role;
+
+  has 'is_broken' => (
+      is  => 'rw',
+      isa => 'Bool',
+  );
+
+  sub break {
+      my $self = shift;
+
+      print "I broke\n";
+
+      $self->is_broken(1);
+  }
+
+Except for our use of C<Moose::Role>, this looks just like a class
+definition with Moose. However, this is not a class, and it cannot be
+instantiated.
+
+Instead, its attributes and methods will be composed into classes
+which use the role:
+
+  package Car;
+
+  use Moose;
+
+  with 'Breakable';
+
+  has 'engine' => (
+      is  => 'ro',
+      isa => 'Engine',
+  );
+
+The C<with> function composes roles into a class. Once that is done,
+the C<Car> class has an C<is_broken> attribute and a C<break>
+method. The C<Car> class also C<does('Breakable')>:
+
+  my $car = Car->new( engine => Engine->new );
+
+  print $car->is_broken ? 'Still working' : 'Busted';
+  $car->break;
+  print $car->is_broken ? 'Still working' : 'Busted';
+
+  $car->does('Breakable'); # true
+
+This prints:
+
+  Still working
+  I broke
+  Busted
+
+We could use this same role in a C<Bone> class:
+
+  package Bone;
+
+  use Moose;
+
+  with 'Breakable';
+
+  has 'marrow' => (
+      is  => 'ro',
+      isa => 'Marrow',
+  );
+
+=head1 REQUIRED METHODS
+
+As mentioned previously, a role can require that consuming classes
+provide one or more methods. Using our C<Breakable> example, let's
+make it require that consuming classes implement their own C<break>
+methods:
+
+  package Breakable;
+
+  use Moose::Role;
+
+  requires 'break';
+
+  has 'is_broken' => (
+      is  => 'rw',
+      isa => 'Bool',
+  );
+
+  after 'break' => sub {
+      my $self = shift;
+
+      $self->is_broken(1);
+  };
+
+If we try to consume this role in a class that does not have a
+C<break> 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<break>. Basically, we want consuming classes to implement their own
+logic for breaking, but we make sure that the C<is_broken> attribute
+is always set to true when C<break> is called.
+
+  package Car
+
+      use Moose;
+
+  with 'Breakable';
+
+  has 'engine' => (
+      is  => 'ro',
+      isa => 'Engine',
+  );
+
+  sub break {
+      my $self = shift;
+
+      if ( $self->is_moving ) {
+          $self->stop;
+      }
+  }
+
+=head1 USING METHOD MODIFIERS
+
+Method modifiers and roles are a very powerful combination.  Often, a
+role will combine method modifiers and required methods. We already
+saw one example with our C<Breakable> example.
+
+Method modifiers increase the complexity of roles, because they make
+the role application order relevant. If a class uses multiple roles,
+each of which modify the same method, those modifiers will be applied
+in the same order as the roles are used:
+
+  package MovieCar;
+
+  use Moose;
+
+  extends 'Car';
+
+  with 'Breakable', 'ExplodesOnBreakage';
+
+Assuming that the new C<ExplodesOnBreakage> method I<also> has an
+C<after> modifier on C<break>, the C<after> modifiers will run one
+after the other. The modifier from C<Breakable> will run first, then
+the one from C<ExplodesOnBreakage>.
+
+=head1 METHOD CONFLICTS
+
+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<own> method of the same name.
+
+  package Breakdances;
+
+  use Moose::Role
+
+  sub break {
+
+  }
+
+If we compose both C<Breakable> and C<Breakdancer> in a class, we must
+provide our own C<break> method:
+
+  package FragileDancer;
+
+  use Moose;
+
+  with 'Breakable', 'Breakdancer';
+
+  sub break { ... }
+
+=head1 METHOD EXCLUSION AND ALIASING
+
+If we want our C<FragileDancer> class to be able to call the methods
+from both its roles, we can alias the methods:
+
+  package FragileDancer;
+
+  use Moose;
+
+  with 'Breakable'   => { alias => { break => 'break_bone' } },
+       'Breakdancer' => { alias => { break => 'break_dance' } };
+
+However, aliasing a method simply makes a I<copy> of the method with
+the new name. We also need to exclude the original name:
+
+  with 'Breakable' => {
+      alias   => { break => 'break_bone' },
+      exclude => 'break',
+      },
+      'Breakdancer' => {
+      alias   => { break => 'break_dance' },
+      exclude => 'break',
+      };
+
+The exclude parameter prevents the C<break> method from being composed
+into the C<FragileDancer> class, so we don't have a conflict. This
+means that C<FragileDancer> does not need to implement its own
+C<break> method.
+
+This is useful, but it's worth noting that this breaks the contract
+implicit in consuming a role. Our C<FragileDancer> class does both the
+C<Breakable> and C<BreakDancer>, but does not provide a C<break>
+method. If some API expects an object that does one of those roles, it
+probably expects it to implement that method.
+
+=head1 AUTHOR
+
+Dave Rolsky E<lt>autarch at urth.orgE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2008 by Infinity Interactive, Inc.
+
+L<http://www.iinteractive.com>
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut




More information about the Moose-commits mailing list