Add pointers from old doc names to new names
Dave Rolsky [Mon, 20 Feb 2012 22:32:44 +0000 (16:32 -0600)]
26 files changed:
lib/Moose/Cookbook/Basics/Recipe1.pod [new file with mode: 0644]
lib/Moose/Cookbook/Basics/Recipe10.pod [new file with mode: 0644]
lib/Moose/Cookbook/Basics/Recipe11.pod [new file with mode: 0644]
lib/Moose/Cookbook/Basics/Recipe2.pod [new file with mode: 0644]
lib/Moose/Cookbook/Basics/Recipe3.pod [new file with mode: 0644]
lib/Moose/Cookbook/Basics/Recipe4.pod [new file with mode: 0644]
lib/Moose/Cookbook/Basics/Recipe5.pod [new file with mode: 0644]
lib/Moose/Cookbook/Basics/Recipe6.pod [new file with mode: 0644]
lib/Moose/Cookbook/Basics/Recipe7.pod [new file with mode: 0644]
lib/Moose/Cookbook/Basics/Recipe8.pod [new file with mode: 0644]
lib/Moose/Cookbook/Basics/Recipe9.pod [new file with mode: 0644]
lib/Moose/Cookbook/Extending/Recipe1.pod [new file with mode: 0644]
lib/Moose/Cookbook/Extending/Recipe2.pod [new file with mode: 0644]
lib/Moose/Cookbook/Extending/Recipe3.pod [new file with mode: 0644]
lib/Moose/Cookbook/Extending/Recipe4.pod [new file with mode: 0644]
lib/Moose/Cookbook/Meta/Recipe1.pod [new file with mode: 0644]
lib/Moose/Cookbook/Meta/Recipe2.pod [new file with mode: 0644]
lib/Moose/Cookbook/Meta/Recipe3.pod [new file with mode: 0644]
lib/Moose/Cookbook/Meta/Recipe4.pod [new file with mode: 0644]
lib/Moose/Cookbook/Meta/Recipe5.pod [new file with mode: 0644]
lib/Moose/Cookbook/Meta/Recipe6.pod [new file with mode: 0644]
lib/Moose/Cookbook/Meta/Recipe7.pod [new file with mode: 0644]
lib/Moose/Cookbook/Roles/Recipe1.pod [new file with mode: 0644]
lib/Moose/Cookbook/Roles/Recipe2.pod [new file with mode: 0644]
lib/Moose/Cookbook/Roles/Recipe3.pod [new file with mode: 0644]
lib/Moose/OldDocs.pm [new file with mode: 0644]

diff --git a/lib/Moose/Cookbook/Basics/Recipe1.pod b/lib/Moose/Cookbook/Basics/Recipe1.pod
new file mode 100644 (file)
index 0000000..c19cadf
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe1;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::Point_AttributesAndSubclassing>
+
+=cut
diff --git a/lib/Moose/Cookbook/Basics/Recipe10.pod b/lib/Moose/Cookbook/Basics/Recipe10.pod
new file mode 100644 (file)
index 0000000..082a6ce
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe10;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::Person_BUILDARGSAndBUILD>
+
+=cut
diff --git a/lib/Moose/Cookbook/Basics/Recipe11.pod b/lib/Moose/Cookbook/Basics/Recipe11.pod
new file mode 100644 (file)
index 0000000..c26732f
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe11;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::DateTime_ExtendingNonMooseParent>
+
+=cut
diff --git a/lib/Moose/Cookbook/Basics/Recipe2.pod b/lib/Moose/Cookbook/Basics/Recipe2.pod
new file mode 100644 (file)
index 0000000..754de52
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe2;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::BankAccount_MethodModifiersAndSubclassing>
+
+=cut
diff --git a/lib/Moose/Cookbook/Basics/Recipe3.pod b/lib/Moose/Cookbook/Basics/Recipe3.pod
new file mode 100644 (file)
index 0000000..3deace6
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe3;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::BinaryTree_AttributeFeatures>
+
+=cut
diff --git a/lib/Moose/Cookbook/Basics/Recipe4.pod b/lib/Moose/Cookbook/Basics/Recipe4.pod
new file mode 100644 (file)
index 0000000..1a8783d
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe4;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::Company_Subtypes>
+
+=cut
diff --git a/lib/Moose/Cookbook/Basics/Recipe5.pod b/lib/Moose/Cookbook/Basics/Recipe5.pod
new file mode 100644 (file)
index 0000000..9f1deff
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe5;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::HTTP_SubtypesAndCoercion>
+
+=cut
diff --git a/lib/Moose/Cookbook/Basics/Recipe6.pod b/lib/Moose/Cookbook/Basics/Recipe6.pod
new file mode 100644 (file)
index 0000000..8c695a2
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe6;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::Document_AugmentAndInner>
+
+=cut
diff --git a/lib/Moose/Cookbook/Basics/Recipe7.pod b/lib/Moose/Cookbook/Basics/Recipe7.pod
new file mode 100644 (file)
index 0000000..da995c3
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe7;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::Immutable>
+
+=cut
diff --git a/lib/Moose/Cookbook/Basics/Recipe8.pod b/lib/Moose/Cookbook/Basics/Recipe8.pod
new file mode 100644 (file)
index 0000000..0d28e25
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe8;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::BinaryTree_BuilderAndLazyBuild>
+
+=cut
diff --git a/lib/Moose/Cookbook/Basics/Recipe9.pod b/lib/Moose/Cookbook/Basics/Recipe9.pod
new file mode 100644 (file)
index 0000000..93e72fa
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Basics::Recipe9;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Basics::Genome_OverloadingSubtypesAndCoercion>
+
+=cut
diff --git a/lib/Moose/Cookbook/Extending/Recipe1.pod b/lib/Moose/Cookbook/Extending/Recipe1.pod
new file mode 100644 (file)
index 0000000..39988fc
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Extending::Recipe1;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Extending::ExtensionOverview>
+
+=cut
diff --git a/lib/Moose/Cookbook/Extending/Recipe2.pod b/lib/Moose/Cookbook/Extending/Recipe2.pod
new file mode 100644 (file)
index 0000000..b8067a6
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Extending::Recipe2;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Extending::Debugging_BaseClassRole>
+
+=cut
diff --git a/lib/Moose/Cookbook/Extending/Recipe3.pod b/lib/Moose/Cookbook/Extending/Recipe3.pod
new file mode 100644 (file)
index 0000000..972e458
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Extending::Recipe3;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Extending::Mooseish_MooseSugar>
+
+=cut
diff --git a/lib/Moose/Cookbook/Extending/Recipe4.pod b/lib/Moose/Cookbook/Extending/Recipe4.pod
new file mode 100644 (file)
index 0000000..c280ea3
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Extending::Recipe4;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Extending::Mooseish_MooseSugar>
+
+=cut
diff --git a/lib/Moose/Cookbook/Meta/Recipe1.pod b/lib/Moose/Cookbook/Meta/Recipe1.pod
new file mode 100644 (file)
index 0000000..3d01f5d
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Meta::Recipe1;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Meta::WhyMeta>
+
+=cut
diff --git a/lib/Moose/Cookbook/Meta/Recipe2.pod b/lib/Moose/Cookbook/Meta/Recipe2.pod
new file mode 100644 (file)
index 0000000..7f9bcaf
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Meta::Recipe2;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Legacy::Labeled_AttributeMetaclass>
+
+=cut
diff --git a/lib/Moose/Cookbook/Meta/Recipe3.pod b/lib/Moose/Cookbook/Meta/Recipe3.pod
new file mode 100644 (file)
index 0000000..7055d8d
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Meta::Recipe3;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Meta::Labeled_AttributeTrait>
+
+=cut
diff --git a/lib/Moose/Cookbook/Meta/Recipe4.pod b/lib/Moose/Cookbook/Meta/Recipe4.pod
new file mode 100644 (file)
index 0000000..7dd3242
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Meta::Recipe4;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Legacy::Table_ClassMetaclass>
+
+=cut
diff --git a/lib/Moose/Cookbook/Meta/Recipe5.pod b/lib/Moose/Cookbook/Meta/Recipe5.pod
new file mode 100644 (file)
index 0000000..3f03949
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Meta::Recipe4;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Meta::Table_MetaclassTrait>
+
+=cut
diff --git a/lib/Moose/Cookbook/Meta/Recipe6.pod b/lib/Moose/Cookbook/Meta/Recipe6.pod
new file mode 100644 (file)
index 0000000..1c37409
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Meta::Recipe6;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Meta::PrivateOrPublic_MethodMetaclass>
+
+=cut
diff --git a/lib/Moose/Cookbook/Meta/Recipe7.pod b/lib/Moose/Cookbook/Meta/Recipe7.pod
new file mode 100644 (file)
index 0000000..c4fa67a
--- /dev/null
@@ -0,0 +1,9 @@
+package Moose::Cookbook::Meta::Recipe6;
+
+__END__
+
+=pod
+
+=head1 RENAMED TO L<Moose::Cookbook::Meta::GlobRef_InstanceMetaclass>
+
+=cut
diff --git a/lib/Moose/Cookbook/Roles/Recipe1.pod b/lib/Moose/Cookbook/Roles/Recipe1.pod
new file mode 100644 (file)
index 0000000..2a3d44a
--- /dev/null
@@ -0,0 +1,318 @@
+package Moose::Cookbook::Roles::Recipe1;
+
+# ABSTRACT: The Moose::Role example
+
+__END__
+
+
+=pod
+
+=head1 SYNOPSIS
+
+  package Eq;
+  use Moose::Role;
+
+  requires 'equal_to';
+
+  sub not_equal_to {
+      my ( $self, $other ) = @_;
+      not $self->equal_to($other);
+  }
+
+  package Comparable;
+  use Moose::Role;
+
+  with 'Eq';
+
+  requires 'compare';
+
+  sub equal_to {
+      my ( $self, $other ) = @_;
+      $self->compare($other) == 0;
+  }
+
+  sub greater_than {
+      my ( $self, $other ) = @_;
+      $self->compare($other) == 1;
+  }
+
+  sub less_than {
+      my ( $self, $other ) = @_;
+      $self->compare($other) == -1;
+  }
+
+  sub greater_than_or_equal_to {
+      my ( $self, $other ) = @_;
+      $self->greater_than($other) || $self->equal_to($other);
+  }
+
+  sub less_than_or_equal_to {
+      my ( $self, $other ) = @_;
+      $self->less_than($other) || $self->equal_to($other);
+  }
+
+  package Printable;
+  use Moose::Role;
+
+  requires 'to_string';
+
+  package US::Currency;
+  use Moose;
+
+  with 'Comparable', 'Printable';
+
+  has 'amount' => ( is => 'rw', isa => 'Num', default => 0 );
+
+  sub compare {
+      my ( $self, $other ) = @_;
+      $self->amount <=> $other->amount;
+  }
+
+  sub to_string {
+      my $self = shift;
+      sprintf '$%0.2f USD' => $self->amount;
+  }
+
+=head1 DESCRIPTION
+
+Roles have two primary purposes: as interfaces, and as a means of code
+reuse. This recipe demonstrates the latter, with roles that define
+comparison and display code for objects.
+
+Let's start with C<Eq>. First, note that we've replaced C<use Moose>
+with C<use Moose::Role>. We also have a new sugar function, C<requires>:
+
+  requires 'equal_to';
+
+This says that any class which consumes this role must provide an
+C<equal_to> method. It can provide this method directly, or by
+consuming some other role.
+
+The C<Eq> role defines its C<not_equal_to> method in terms of the
+required C<equal_to> method. This lets us minimize the methods that
+consuming classes must provide.
+
+The next role, C<Comparable>, builds on the C<Eq> role. We include
+C<Eq> in C<Comparable> using C<with>, another new sugar function:
+
+  with 'Eq';
+
+The C<with> function takes a list of roles to consume. In our example,
+the C<Comparable> role provides the C<equal_to> method required by
+C<Eq>. However, it could opt not to, in which case a class that
+consumed C<Comparable> would have to provide its own C<equal_to>. In
+other words, a role can consume another role I<without> providing any
+required methods.
+
+The C<Comparable> role requires a method,  C<compare>:
+
+  requires 'compare';
+
+The C<Comparable> role also provides a number of other methods, all of
+which ultimately rely on C<compare>.
+
+  sub equal_to {
+      my ( $self, $other ) = @_;
+      $self->compare($other) == 0;
+  }
+
+  sub greater_than {
+      my ( $self, $other ) = @_;
+      $self->compare($other) == 1;
+  }
+
+  sub less_than {
+      my ( $self, $other ) = @_;
+      $self->compare($other) == -1;
+  }
+
+  sub greater_than_or_equal_to {
+      my ( $self, $other ) = @_;
+      $self->greater_than($other) || $self->equal_to($other);
+  }
+
+  sub less_than_or_equal_to {
+      my ( $self, $other ) = @_;
+      $self->less_than($other) || $self->equal_to($other);
+  }
+
+Finally, we define the C<Printable> role. This role exists solely to
+provide an interface. It has no methods, just a list of required methods.
+In this case, it just requires a C<to_string> method.
+
+An interface role is useful because it defines both a method and a
+I<name>. We know that any class which does this role has a
+C<to_string> method, but we can also assume that this method has the
+semantics we want. Presumably, in real code we would define those
+semantics in the documentation for the C<Printable> role. (1)
+
+Finally, we have the C<US::Currency> class which consumes both the
+C<Comparable> and C<Printable> roles.
+
+  with 'Comparable', 'Printable';
+
+It also defines a regular Moose attribute, C<amount>:
+
+  has 'amount' => ( is => 'rw', isa => 'Num', default => 0 );
+
+Finally we see the implementation of the methods required by our
+roles. We have a C<compare> method:
+
+  sub compare {
+      my ( $self, $other ) = @_;
+      $self->amount <=> $other->amount;
+  }
+
+By consuming the C<Comparable> role and defining this method, we gain
+the following methods for free: C<equal_to>, C<greater_than>,
+C<less_than>, C<greater_than_or_equal_to> and
+C<less_than_or_equal_to>.
+
+Then we have our C<to_string> method:
+
+  sub to_string {
+      my $self = shift;
+      sprintf '$%0.2f USD' => $self->amount;
+  }
+
+=head1 CONCLUSION
+
+Roles can be very powerful. They are a great way of encapsulating
+reusable behavior, as well as communicating (semantic and interface)
+information about the methods our classes provide.
+
+=head1 FOOTNOTES
+
+=over 4
+
+=item (1)
+
+Consider two classes, C<Runner> and C<Process>, both of which define a
+C<run> method. If we just require that an object implements a C<run>
+method, we still aren't saying anything about what that method
+I<actually does>. If we require an object that implements the
+C<Executable> role, we're saying something about semantics.
+
+=back
+
+=begin testing
+
+ok( US::Currency->does('Comparable'), '... US::Currency does Comparable' );
+ok( US::Currency->does('Eq'),         '... US::Currency does Eq' );
+ok( US::Currency->does('Printable'),  '... US::Currency does Printable' );
+
+my $hundred = US::Currency->new( amount => 100.00 );
+isa_ok( $hundred, 'US::Currency' );
+
+ok( $hundred->DOES("US::Currency"), "UNIVERSAL::DOES for class" );
+ok( $hundred->DOES("Comparable"),   "UNIVERSAL::DOES for role" );
+
+can_ok( $hundred, 'amount' );
+is( $hundred->amount, 100, '... got the right amount' );
+
+can_ok( $hundred, 'to_string' );
+is( $hundred->to_string, '$100.00 USD',
+    '... got the right stringified value' );
+
+ok( $hundred->does('Comparable'), '... US::Currency does Comparable' );
+ok( $hundred->does('Eq'),         '... US::Currency does Eq' );
+ok( $hundred->does('Printable'),  '... US::Currency does Printable' );
+
+my $fifty = US::Currency->new( amount => 50.00 );
+isa_ok( $fifty, 'US::Currency' );
+
+can_ok( $fifty, 'amount' );
+is( $fifty->amount, 50, '... got the right amount' );
+
+can_ok( $fifty, 'to_string' );
+is( $fifty->to_string, '$50.00 USD', '... got the right stringified value' );
+
+ok( $hundred->greater_than($fifty),             '... 100 gt 50' );
+ok( $hundred->greater_than_or_equal_to($fifty), '... 100 ge 50' );
+ok( !$hundred->less_than($fifty),               '... !100 lt 50' );
+ok( !$hundred->less_than_or_equal_to($fifty),   '... !100 le 50' );
+ok( !$hundred->equal_to($fifty),                '... !100 eq 50' );
+ok( $hundred->not_equal_to($fifty),             '... 100 ne 50' );
+
+ok( !$fifty->greater_than($hundred),             '... !50 gt 100' );
+ok( !$fifty->greater_than_or_equal_to($hundred), '... !50 ge 100' );
+ok( $fifty->less_than($hundred),                 '... 50 lt 100' );
+ok( $fifty->less_than_or_equal_to($hundred),     '... 50 le 100' );
+ok( !$fifty->equal_to($hundred),                 '... !50 eq 100' );
+ok( $fifty->not_equal_to($hundred),              '... 50 ne 100' );
+
+ok( !$fifty->greater_than($fifty),            '... !50 gt 50' );
+ok( $fifty->greater_than_or_equal_to($fifty), '... !50 ge 50' );
+ok( !$fifty->less_than($fifty),               '... 50 lt 50' );
+ok( $fifty->less_than_or_equal_to($fifty),    '... 50 le 50' );
+ok( $fifty->equal_to($fifty),                 '... 50 eq 50' );
+ok( !$fifty->not_equal_to($fifty),            '... !50 ne 50' );
+
+## ... check some meta-stuff
+
+# Eq
+
+my $eq_meta = Eq->meta;
+isa_ok( $eq_meta, 'Moose::Meta::Role' );
+
+ok( $eq_meta->has_method('not_equal_to'), '... Eq has_method not_equal_to' );
+ok( $eq_meta->requires_method('equal_to'),
+    '... Eq requires_method not_equal_to' );
+
+# Comparable
+
+my $comparable_meta = Comparable->meta;
+isa_ok( $comparable_meta, 'Moose::Meta::Role' );
+
+ok( $comparable_meta->does_role('Eq'), '... Comparable does Eq' );
+
+foreach my $method_name (
+    qw(
+    equal_to not_equal_to
+    greater_than greater_than_or_equal_to
+    less_than less_than_or_equal_to
+    )
+    ) {
+    ok( $comparable_meta->has_method($method_name),
+        '... Comparable has_method ' . $method_name );
+}
+
+ok( $comparable_meta->requires_method('compare'),
+    '... Comparable requires_method compare' );
+
+# Printable
+
+my $printable_meta = Printable->meta;
+isa_ok( $printable_meta, 'Moose::Meta::Role' );
+
+ok( $printable_meta->requires_method('to_string'),
+    '... Printable requires_method to_string' );
+
+# US::Currency
+
+my $currency_meta = US::Currency->meta;
+isa_ok( $currency_meta, 'Moose::Meta::Class' );
+
+ok( $currency_meta->does_role('Comparable'),
+    '... US::Currency does Comparable' );
+ok( $currency_meta->does_role('Eq'), '... US::Currency does Eq' );
+ok( $currency_meta->does_role('Printable'),
+    '... US::Currency does Printable' );
+
+foreach my $method_name (
+    qw(
+    amount
+    equal_to not_equal_to
+    compare
+    greater_than greater_than_or_equal_to
+    less_than less_than_or_equal_to
+    to_string
+    )
+    ) {
+    ok( $currency_meta->has_method($method_name),
+        '... US::Currency has_method ' . $method_name );
+}
+
+=end testing
+
+=cut
diff --git a/lib/Moose/Cookbook/Roles/Recipe2.pod b/lib/Moose/Cookbook/Roles/Recipe2.pod
new file mode 100644 (file)
index 0000000..096abfd
--- /dev/null
@@ -0,0 +1,169 @@
+package Moose::Cookbook::Roles::Recipe2;
+
+# ABSTRACT: Advanced Role Composition - method exclusion and aliasing
+
+__END__
+
+
+=pod
+
+=head1 SYNOPSIS
+
+  package Restartable;
+  use Moose::Role;
+
+  has 'is_paused' => (
+      is      => 'rw',
+      isa     => 'Bool',
+      default => 0,
+  );
+
+  requires 'save_state', 'load_state';
+
+  sub stop { 1 }
+
+  sub start { 1 }
+
+  package Restartable::ButUnreliable;
+  use Moose::Role;
+
+  with 'Restartable' => {
+      -alias => {
+          stop  => '_stop',
+          start => '_start'
+      },
+      -excludes => [ 'stop', 'start' ],
+  };
+
+  sub stop {
+      my $self = shift;
+
+      $self->explode() if rand(1) > .5;
+
+      $self->_stop();
+  }
+
+  sub start {
+      my $self = shift;
+
+      $self->explode() if rand(1) > .5;
+
+      $self->_start();
+  }
+
+  package Restartable::ButBroken;
+  use Moose::Role;
+
+  with 'Restartable' => { -excludes => [ 'stop', 'start' ] };
+
+  sub stop {
+      my $self = shift;
+
+      $self->explode();
+  }
+
+  sub start {
+      my $self = shift;
+
+      $self->explode();
+  }
+
+=head1 DESCRIPTION
+
+In this example, we demonstrate how to exercise fine-grained control
+over what methods we consume from a role. We have a C<Restartable>
+role which provides an C<is_paused> attribute, and two methods,
+C<stop> and C<start>.
+
+Then we have two more roles which implement the same interface, each
+putting their own spin on the C<stop> and C<start> methods.
+
+In the C<Restartable::ButUnreliable> role, we want to provide a new
+implementation of C<stop> and C<start>, but still have access to the
+original implementation. To do this, we alias the methods from
+C<Restartable> to private methods, and provide wrappers around the
+originals (1).
+
+Note that aliasing simply I<adds> a name, so we also need to exclude the
+methods with their original names.
+
+  with 'Restartable' => {
+      -alias => {
+          stop  => '_stop',
+          start => '_start'
+      },
+      -excludes => [ 'stop', 'start' ],
+  };
+
+In the C<Restartable::ButBroken> role, we want to provide an entirely
+new behavior for C<stop> and C<start>. We exclude them entirely when
+composing the C<Restartable> role into C<Restartable::ButBroken>.
+
+It's worth noting that the C<-excludes> parameter also accepts a single
+string as an argument if you just want to exclude one method.
+
+  with 'Restartable' => { -excludes => [ 'stop', 'start' ] };
+
+=head1 CONCLUSION
+
+Exclusion and renaming are a power tool that can be handy, especially
+when building roles out of other roles. In this example, all of our
+roles implement the C<Restartable> role. Each role provides same API,
+but each has a different implementation under the hood.
+
+You can also use the method aliasing and excluding features when
+composing a role into a class.
+
+=head1 FOOTNOTES
+
+=over 4
+
+=item (1)
+
+The mention of wrapper should tell you that we could do the same thing
+using method modifiers, but for the sake of this example, we don't.
+
+=back
+
+=begin testing
+
+{
+    my $unreliable = Moose::Meta::Class->create_anon_class(
+        superclasses => [],
+        roles        => [qw/Restartable::ButUnreliable/],
+        methods      => {
+            explode      => sub { },    # nop.
+            'save_state' => sub { },
+            'load_state' => sub { },
+        },
+    )->new_object();
+    ok( $unreliable, 'made anon class with Restartable::ButUnreliable role' );
+    can_ok( $unreliable, qw/start stop/ );
+}
+
+{
+    my $cnt    = 0;
+    my $broken = Moose::Meta::Class->create_anon_class(
+        superclasses => [],
+        roles        => [qw/Restartable::ButBroken/],
+        methods      => {
+            explode      => sub { $cnt++ },
+            'save_state' => sub { },
+            'load_state' => sub { },
+        },
+    )->new_object();
+
+    ok( $broken, 'made anon class with Restartable::ButBroken role' );
+
+    $broken->start();
+
+    is( $cnt, 1, '... start called explode' );
+
+    $broken->stop();
+
+    is( $cnt, 2, '... stop also called explode' );
+}
+
+=end testing
+
+=cut
diff --git a/lib/Moose/Cookbook/Roles/Recipe3.pod b/lib/Moose/Cookbook/Roles/Recipe3.pod
new file mode 100644 (file)
index 0000000..b81c9f4
--- /dev/null
@@ -0,0 +1,131 @@
+package Moose::Cookbook::Roles::Recipe3;
+
+# ABSTRACT: Applying a role to an object instance
+
+__END__
+
+package Moose::Cookbook::Roles::Recipe3;
+
+=pod
+
+=begin testing-SETUP
+
+{
+    # Not in the recipe, but needed for writing tests.
+    package Employee;
+
+    use Moose;
+
+    has 'name' => (
+        is       => 'ro',
+        isa      => 'Str',
+        required => 1,
+    );
+
+    has 'work' => (
+        is        => 'rw',
+        isa       => 'Str',
+        predicate => 'has_work',
+    );
+}
+
+=end testing-SETUP
+
+=head1 SYNOPSIS
+
+  package MyApp::Role::Job::Manager;
+
+  use List::Util qw( first );
+
+  use Moose::Role;
+
+  has 'employees' => (
+      is  => 'rw',
+      isa => 'ArrayRef[Employee]',
+  );
+
+  sub assign_work {
+      my $self = shift;
+      my $work = shift;
+
+      my $employee = first { !$_->has_work } @{ $self->employees };
+
+      die 'All my employees have work to do!' unless $employee;
+
+      $employee->work($work);
+  }
+
+  package main;
+
+  my $lisa = Employee->new( name => 'Lisa' );
+  MyApp::Role::Job::Manager->meta->apply($lisa);
+
+  my $homer = Employee->new( name => 'Homer' );
+  my $bart  = Employee->new( name => 'Bart' );
+  my $marge = Employee->new( name => 'Marge' );
+
+  $lisa->employees( [ $homer, $bart, $marge ] );
+  $lisa->assign_work('mow the lawn');
+
+=head1 DESCRIPTION
+
+In this recipe, we show how a role can be applied to an object. In
+this specific case, we are giving an employee managerial
+responsibilities.
+
+Applying a role to an object is simple. The L<Moose::Meta::Role>
+object provides an C<apply> method. This method will do the right
+thing when given an object instance.
+
+  MyApp::Role::Job::Manager->meta->apply($lisa);
+
+We could also use the C<apply_all_roles> function from L<Moose::Util>.
+
+  apply_all_roles( $person, MyApp::Role::Job::Manager->meta );
+
+The main advantage of using C<apply_all_roles> is that it can be used
+to apply more than one role at a time.
+
+We could also pass parameters to the role we're applying:
+
+  MyApp::Role::Job::Manager->meta->apply(
+      $lisa,
+      -alias => { assign_work => 'get_off_your_lazy_behind' },
+  );
+
+We saw examples of how method exclusion and alias working in L<roles
+recipe 2|Moose::Cookbook::Roles::Recipe2>.
+
+=head1 CONCLUSION
+
+Applying a role to an object instance is a useful tool for adding
+behavior to existing objects. In our example, it is effective used to
+model a promotion.
+
+It can also be useful as a sort of controlled monkey-patching for
+existing code, particularly non-Moose code. For example, you could
+create a debugging role and apply it to an object at runtime.
+
+=begin testing
+
+{
+    my $lisa = Employee->new( name => 'Lisa' );
+    MyApp::Role::Job::Manager->meta->apply($lisa);
+
+    my $homer = Employee->new( name => 'Homer' );
+    my $bart  = Employee->new( name => 'Bart' );
+    my $marge = Employee->new( name => 'Marge' );
+
+    $lisa->employees( [ $homer, $bart, $marge ] );
+    $lisa->assign_work('mow the lawn');
+
+    ok( $lisa->does('MyApp::Role::Job::Manager'),
+        'lisa now does the manager role' );
+
+    is( $homer->work, 'mow the lawn',
+        'homer was assigned a task by lisa' );
+}
+
+=end testing
+
+=cut
diff --git a/lib/Moose/OldDocs.pm b/lib/Moose/OldDocs.pm
new file mode 100644 (file)
index 0000000..c648c43
--- /dev/null
@@ -0,0 +1,5 @@
+package Moose::OldDocs;
+
+# ABSTRACT: A distro that contains stubs for documentation which has moved.
+
+__END__