Add changes $NEXT
[gitmo/Moose.git] / lib / Moose / Cookbook / Roles / Recipe1.pod
CommitLineData
a7d0cd00 1
2=pod
3
4=head1 NAME
5
021b8139 6Moose::Cookbook::Roles::Recipe1 - The Moose::Role example
a7d0cd00 7
8=head1 SYNOPSIS
9e93dd19 9
446e850f 10 package Eq;
a7d0cd00 11 use Moose::Role;
a39ea7dc 12
446e850f 13 requires 'equal_to';
a39ea7dc 14
15 sub not_equal_to {
16 my ( $self, $other ) = @_;
9e93dd19 17 not $self->equal_to($other);
a7d0cd00 18 }
a39ea7dc 19
9e93dd19 20 package Comparable;
a7d0cd00 21 use Moose::Role;
a39ea7dc 22
446e850f 23 with 'Eq';
a39ea7dc 24
446e850f 25 requires 'compare';
a39ea7dc 26
446e850f 27 sub equal_to {
a39ea7dc 28 my ( $self, $other ) = @_;
446e850f 29 $self->compare($other) == 0;
a39ea7dc 30 }
31
446e850f 32 sub greater_than {
a39ea7dc 33 my ( $self, $other ) = @_;
446e850f 34 $self->compare($other) == 1;
a39ea7dc 35 }
36
446e850f 37 sub less_than {
a39ea7dc 38 my ( $self, $other ) = @_;
446e850f 39 $self->compare($other) == -1;
a7d0cd00 40 }
a39ea7dc 41
446e850f 42 sub greater_than_or_equal_to {
a39ea7dc 43 my ( $self, $other ) = @_;
446e850f 44 $self->greater_than($other) || $self->equal_to($other);
a39ea7dc 45 }
46
446e850f 47 sub less_than_or_equal_to {
a39ea7dc 48 my ( $self, $other ) = @_;
446e850f 49 $self->less_than($other) || $self->equal_to($other);
a39ea7dc 50 }
51
9e93dd19 52 package Printable;
9e93dd19 53 use Moose::Role;
a39ea7dc 54
55 requires 'to_string';
56
446e850f 57 package US::Currency;
a7d0cd00 58 use Moose;
a39ea7dc 59
9e93dd19 60 with 'Comparable', 'Printable';
a39ea7dc 61
62 has 'amount' => ( is => 'rw', isa => 'Num', default => 0 );
63
446e850f 64 sub compare {
a39ea7dc 65 my ( $self, $other ) = @_;
446e850f 66 $self->amount <=> $other->amount;
67 }
a39ea7dc 68
9e93dd19 69 sub to_string {
70 my $self = shift;
a39ea7dc 71 sprintf '$%0.2f USD' => $self->amount;
9e93dd19 72 }
cb26ee7e 73
a7d0cd00 74=head1 DESCRIPTION
75
efaf28e9 76Roles have two primary purposes: as interfaces, and as a means of code
77reuse. This recipe demonstrates the latter, with roles that define
78comparison and display code for objects.
cb26ee7e 79
efaf28e9 80Let's start with CB<Eq>. First, note that we've replaced C<use Moose>
81with C<use Moose::Role>. We also have a new sugar function, C<required>:
cb26ee7e 82
83 requires 'equal_to';
84
efaf28e9 85This says that any class which consumes this role must provide an
86C<equal_to> method. It can provide this method directly, or by
87consuming some other role.
cb26ee7e 88
efaf28e9 89The C<Eq> role defines its C<not_equal_to> method in terms of the
90required C<equal_to> method. This lets us minimize the methods that
91consuming classes must provide.
cb26ee7e 92
efaf28e9 93The next role, C<Comparable>, builds on the C<Eq> role. We include
94C<Eq> in C<Comparable> using C<with>, another new sugar function:
cb26ee7e 95
96 with 'Eq';
97
efaf28e9 98The C<with> function takes a list of roles to consume. In our example,
99the C<Comparable> role provides the C<equal_to> method required by
100C<Eq>. However, it could opt not to, in which case a class that
101consumed C<Comparable> would have to provide its own C<equal_to>. In
102other words, a role can consume another role I<without> providing any
103required methods.
cb26ee7e 104
efaf28e9 105The C<Comparable> role requires a method, C<compare>:
cb26ee7e 106
107 requires 'compare';
108
efaf28e9 109The C<Comparable> role also provides a number of other methods, all of
110which ultimately rely on C<compare>.
cb26ee7e 111
112 sub equal_to {
a39ea7dc 113 my ( $self, $other ) = @_;
cb26ee7e 114 $self->compare($other) == 0;
115 }
a39ea7dc 116
cb26ee7e 117 sub greater_than {
a39ea7dc 118 my ( $self, $other ) = @_;
cb26ee7e 119 $self->compare($other) == 1;
a39ea7dc 120 }
121
cb26ee7e 122 sub less_than {
a39ea7dc 123 my ( $self, $other ) = @_;
cb26ee7e 124 $self->compare($other) == -1;
125 }
a39ea7dc 126
cb26ee7e 127 sub greater_than_or_equal_to {
a39ea7dc 128 my ( $self, $other ) = @_;
cb26ee7e 129 $self->greater_than($other) || $self->equal_to($other);
a39ea7dc 130 }
131
cb26ee7e 132 sub less_than_or_equal_to {
a39ea7dc 133 my ( $self, $other ) = @_;
cb26ee7e 134 $self->less_than($other) || $self->equal_to($other);
135 }
136
efaf28e9 137Finally, we the C<Printable> role. This role exists solely to provide
138an interface. It has no methods, just a list of required methods. In
139this case, it just requires a C<to_string> method.
cb26ee7e 140
efaf28e9 141An interface role is useful because it defines both a method and a
142I<name>. We know that any class which does this role has a
143C<to_string> method, but we can also assume that this method has the
144semantics we want. Presumably, in real code we would define those
145semantics in the documentation for the C<Printable> role. (1)
146
147Finally, we have the C<US::Currency> class which consumes both the
148C<Comparable> and C<Printable> roles.
cb26ee7e 149
150 with 'Comparable', 'Printable';
151
efaf28e9 152It also defines a regular Moose attribute, C<amount>:
cb26ee7e 153
a39ea7dc 154 has 'amount' => ( is => 'rw', isa => 'Num', default => 0 );
cb26ee7e 155
efaf28e9 156Finally we see the implementation of the methods required by our
157roles. We have a C<compare> method:
cb26ee7e 158
159 sub compare {
a39ea7dc 160 my ( $self, $other ) = @_;
cb26ee7e 161 $self->amount <=> $other->amount;
162 }
163
efaf28e9 164By consuming the C<Comparable> role and defining this method, we gain
165the following methods for free: C<equal_to>, C<greater_than>,
166C<less_than>, C<greater_than_or_equal_to> and
cb26ee7e 167C<less_than_or_equal_to>.
168
efaf28e9 169Then we have our C<to_string> method:
cb26ee7e 170
171 sub to_string {
172 my $self = shift;
a39ea7dc 173 sprintf '$%0.2f USD' => $self->amount;
cb26ee7e 174 }
175
176=head1 CONCLUSION
177
efaf28e9 178Roles can very powerful. They are a great way of encapsulating
179reusable behavior, as well as communicating (semantic and interface)
180information about the methods our classes provide.
cb26ee7e 181
182=head1 FOOTNOTES
183
184=over 4
185
186=item (1)
187
efaf28e9 188Consider two classes, C<Runner> and C<Process>, both of which define a
189C<run> method. If we just require that an object implements a C<run>
190method, we still aren't saying anything about what that method
191I<actually does>. If we require an object that implements the
192C<Executable> role, we're saying something about semantics.
cb26ee7e 193
194=back
a7d0cd00 195
efaf28e9 196=head1 AUTHORS
a7d0cd00 197
198Stevan Little E<lt>stevan@iinteractive.comE<gt>
199
efaf28e9 200Dave Rolsky E<lt>autarch@urth.orgE<gt>
201
a7d0cd00 202=head1 COPYRIGHT AND LICENSE
203
2840a3b2 204Copyright 2006-2009 by Infinity Interactive, Inc.
a7d0cd00 205
206L<http://www.iinteractive.com>
207
208This library is free software; you can redistribute it and/or modify
209it under the same terms as Perl itself.
210
a39ea7dc 211=cut