6 Moose::Cookbook::Roles::Recipe1 - The Moose::Role example
16 my ( $self, $other ) = @_;
17 not $self->equal_to($other);
28 my ( $self, $other ) = @_;
29 $self->compare($other) == 0;
33 my ( $self, $other ) = @_;
34 $self->compare($other) == 1;
38 my ( $self, $other ) = @_;
39 $self->compare($other) == -1;
42 sub greater_than_or_equal_to {
43 my ( $self, $other ) = @_;
44 $self->greater_than($other) || $self->equal_to($other);
47 sub less_than_or_equal_to {
48 my ( $self, $other ) = @_;
49 $self->less_than($other) || $self->equal_to($other);
60 with 'Comparable', 'Printable';
62 has 'amount' => ( is => 'rw', isa => 'Num', default => 0 );
65 my ( $self, $other ) = @_;
66 $self->amount <=> $other->amount;
71 sprintf '$%0.2f USD' => $self->amount;
76 In this recipe we examine the role support provided in Moose. "Roles" may be
77 described in many ways, but there are two main ways in which they are used: as
78 interfaces, and as a means of code reuse. This recipe demonstrates the
79 construction and incorporation of roles that define comparison and display of
82 Let's start by examining B<Eq>. You'll notice that instead of the familiar C<use
83 Moose> you might be expecting, here we use C<Moose::Role> to make it clear that
84 this is a role. We encounter a new keyword, C<requires>:
88 What this does is to indicate that any class which "consumes" (that is to say,
89 "includes using C<with>", as we'll see a little later) the B<Eq> role I<must>
90 include an C<equal_to> method, whether this is provided by the class itself, one
91 of its superclasses, or another role consumed by the class (1).
93 In addition to requiring an C<equal_to> method, B<Eq> defines a C<not_equal_to>
94 method, which simply inverts the result of C<equal_to>. Defining additional
95 methods in this way, by using only a few base methods that target classes must
96 define, is a useful pattern to provide maximum functionality with minimum
99 After the minimal B<Eq>, we next move on to B<Comparable>. The first thing you
100 will notice is another new keyword, C<with>:
104 C<with> is used to provide a list of roles which this class (or role) consumes.
105 Here, B<Comparable> only consumes one role (B<Eq>). In effect, it is as if we
106 defined a C<not_equal_to> method within Comparable, and also promised to fulfill
107 the requirement of an C<equal_to> method.
109 B<Comparable> itself states that it requires C<compare>. Again, it means that
110 any classes consuming this role must implement a C<compare> method.
114 B<Comparable> defines an C<equal_to> method which satisfies the B<Eq> role's
115 requirements. This, along with a number of other methods (C<greater_than>,
116 C<less_than>, C<greater_than_or_equal_to>, and C<less_than_or_equal_to>) is
117 simply defined in terms of C<compare>, once again demonstrating the pattern of
118 defining a number of utility methods in terms of only a single method that the
119 target class need implement.
122 my ( $self, $other ) = @_;
123 $self->compare($other) == 0;
127 my ( $self, $other ) = @_;
128 $self->compare($other) == 1;
132 my ( $self, $other ) = @_;
133 $self->compare($other) == -1;
136 sub greater_than_or_equal_to {
137 my ( $self, $other ) = @_;
138 $self->greater_than($other) || $self->equal_to($other);
141 sub less_than_or_equal_to {
142 my ( $self, $other ) = @_;
143 $self->less_than($other) || $self->equal_to($other);
146 Next up is B<Printable>. This is a very simple role, akin to B<Eq>. It merely
147 requires a C<to_string> method. Roles that only require methods are very much
148 like Java's interfaces. If we know that a class does the B<Printable> role, it
149 not only tells us that we can call the C<to_string> method on it, but also that
150 C<to_string> has the precise semantics we want (consider classes B<Tree> and
151 B<Dog>, both with method C<bark>).
153 Finally, we come to B<US::Currency>, a class that allows us to reap the benefits
154 of our hard work. This is a regular Moose class, so we include the normal C<use
155 Moose>. It consumes both B<Comparable> and B<Printable>, as the following line
158 with 'Comparable', 'Printable';
160 It also defines a regular Moose attribute, C<amount>, with a type constraint of
161 C<Num> and a default of C<0>:
163 has 'amount' => ( is => 'rw', isa => 'Num', default => 0 );
165 Now we come to the core of the class. First up, we define a C<compare> method:
168 my ( $self, $other ) = @_;
169 $self->amount <=> $other->amount;
172 As you can see, it simply compares the C<amount> attribute of this object with
173 the C<amount> attribute of the other object passed to it. With the single
174 definition of this method, we gain the following methods for free: C<equal_to>,
175 C<greater_than>, C<less_than>, C<greater_than_or_equal_to> and
176 C<less_than_or_equal_to>.
178 We end the class with a definition of the C<to_string> method, which formats the
179 C<amount> attribute for display:
183 sprintf '$%0.2f USD' => $self->amount;
188 This recipe has shown that roles can be very powerful and immensely useful, and
189 save a great deal of repetition.
197 At present, method requirements from roles cannot be satisfied by attribute
198 accessors. This is a limitation of Moose, and will most likely be rectified in a
205 Stevan Little E<lt>stevan@iinteractive.comE<gt>
207 =head1 COPYRIGHT AND LICENSE
209 Copyright 2006-2009 by Infinity Interactive, Inc.
211 L<http://www.iinteractive.com>
213 This library is free software; you can redistribute it and/or modify
214 it under the same terms as Perl itself.