Commit | Line | Data |
696cf5df |
1 | =pod |
2 | |
f7435595 |
3 | =head1 NAME |
4 | |
5 | Moose::Manual::BestPractices - Get the most out of Moose |
6 | |
fd8a7262 |
7 | =head1 RECOMMENDATIONS |
8 | |
3bfacd05 |
9 | Moose has a lot of features, and there's definitely more than one way |
10 | to do it. However, we think that picking a subset of these features |
11 | and using them consistently makes everyone's life easier. |
12 | |
13 | Of course, as with any list of "best practices", these are really just |
14 | opinions. Feel free to ignore us. |
15 | |
1af5d116 |
16 | =head2 C<namespace::autoclean> and immutabilize |
fd8a7262 |
17 | |
1af5d116 |
18 | We recommend that you remove the Moose sugar and end your Moose class |
19 | definitions by making your class immutable. |
fd8a7262 |
20 | |
21 | package Person; |
22 | |
23 | use Moose; |
1af5d116 |
24 | use namespace::autoclean; |
fd8a7262 |
25 | |
26 | # extends, roles, attributes, etc. |
27 | |
28 | # methods |
29 | |
fd8a7262 |
30 | __PACKAGE__->meta->make_immutable; |
31 | |
32 | 1; |
33 | |
1af5d116 |
34 | The C<use namespace::autoclean> bit is simply good code hygiene, as it removes |
35 | imported symbols from you class's namespace at the end of your package's |
36 | compile cycle, including Moose keywords. Once the class has been |
5481b153 |
37 | built, these keywords are not needed needed. The C<make_immutable> |
38 | call allows Moose to speed up a lot of things, most notably object |
dd8a021c |
39 | construction. The trade-off is that you can no longer change the class |
5481b153 |
40 | definition. |
41 | |
1af5d116 |
42 | C<no Moose;> may be used to unimport only Moose's imported symbols. |
43 | L<namespace::clean> provides finer-grained control than L<namespace::autoclean>. |
e62951ce |
44 | |
1ad2aa8e |
45 | =head2 Never override C<new> |
46 | |
47 | Overriding C<new> is a very bad practice. Instead, you should use a |
48 | C<BUILD> or C<BUILDARGS> methods to do the same thing. When you |
49 | override C<new>, Moose can no longer inline a constructor when your |
19320607 |
50 | class is immutabilized. |
1ad2aa8e |
51 | |
46c52442 |
52 | There are two good reasons to override C<new>. One, you are writing a |
53 | MooseX extension that provides its own L<Moose::Object> subclass |
54 | I<and> a subclass of L<Moose::Meta::Method::Constructor> to inline the |
55 | constructor. Two, you are subclassing a non-Moose parent. |
1ad2aa8e |
56 | |
57 | If you know how to do that, you know when to ignore this best practice |
58 | ;) |
59 | |
d67ce58f |
60 | =head2 Always call C<SUPER::BUILDARGS> |
fd8a7262 |
61 | |
3bfacd05 |
62 | If you override the C<BUILDARGS> method in your class, make sure to |
63 | play nice and call C<SUPER::BUILDARGS> to handle cases you're not |
0f62a437 |
64 | checking for explicitly. |
3bfacd05 |
65 | |
66 | The default C<BUILDARGS> method in L<Moose::Object> handles both a |
67 | list and hashref of named parameters correctly, and also checks for a |
68 | I<non-hashref> single argument. |
69 | |
1ad2aa8e |
70 | =head2 Provide defaults whenever possible, otherwise use C<required> |
3bfacd05 |
71 | |
1ad2aa8e |
72 | When your class provides defaults, this makes constructing new objects |
73 | simpler. If you cannot provide a default, consider making the |
74 | attribute C<required>. |
75 | |
76 | If you don't do either, an attribute can simply be left unset, |
77 | increasing the complexity of your object, because it has more possible |
78 | states that you or the user of your class must account for. |
3bfacd05 |
79 | |
d67ce58f |
80 | =head2 Use C<builder> instead of C<default> most of the time |
3bfacd05 |
81 | |
82 | Builders can be inherited, they have explicit names, and they're just |
83 | plain cleaner. |
84 | |
85 | However, I<do> use a default when the default is a non-reference, |
86 | I<or> when the default is simply an empty reference of some sort. |
87 | |
88 | Also, keep your builder methods private. |
fd8a7262 |
89 | |
0c39debe |
90 | =head2 Use C<lazy_build> |
fd8a7262 |
91 | |
3bfacd05 |
92 | Lazy is good, and often solves initialization ordering problems. It's |
93 | also good for deferring work that may never have to be done. If you're |
e691bebf |
94 | going to be lazy, use C<lazy_build> to save yourself some typing and |
3bfacd05 |
95 | standardize names. |
fd8a7262 |
96 | |
d67ce58f |
97 | =head2 Consider keeping clearers and predicates private |
fd8a7262 |
98 | |
3bfacd05 |
99 | Does everyone I<really> need to be able to clear an attribute? |
100 | Probably not. Don't expose this functionality outside your class |
101 | by default. |
b6477964 |
102 | |
3bfacd05 |
103 | Predicates are less problematic, but there's no reason to make your |
104 | public API bigger than it has to be. |
fd8a7262 |
105 | |
d67ce58f |
106 | =head2 Default to read-only, and consider keeping writers private |
fd8a7262 |
107 | |
3bfacd05 |
108 | Making attributes mutable just means more complexity to account for in |
109 | your program. The alternative to mutable state is to encourage users |
110 | of your class to simply make new objects as needed. |
fd8a7262 |
111 | |
3bfacd05 |
112 | If you I<must> make an attribute read-write, consider making the |
113 | writer a separate private method. Narrower APIs are easy to maintain, |
114 | and mutable state is trouble. |
b6477964 |
115 | |
8a68781d |
116 | In order to declare such attributes, provide a private C<writer> |
117 | parameter: |
118 | |
119 | has pizza => ( |
743e0199 |
120 | is => 'ro', |
121 | isa => 'Pizza', |
122 | writer => '_pizza', |
8a68781d |
123 | ); |
124 | |
d67ce58f |
125 | =head2 Think twice before changing an attribute's type in a subclass |
541027c5 |
126 | |
3bfacd05 |
127 | Down this path lies great confusion. If the attribute is an object |
128 | itself, at least make sure that it has the same interface as the type |
129 | of object in the parent class. |
130 | |
1ad2aa8e |
131 | =head2 Don't use the C<initializer> feature |
132 | |
133 | Don't know what we're talking about? That's fine. |
134 | |
e4a134ed |
135 | =head2 Use L<Moose::Meta::Attribute::Native> traits instead of C<auto_deref> |
3bfacd05 |
136 | |
dc747917 |
137 | The C<auto_deref> feature is a bit troublesome. Directly exposing a |
3bfacd05 |
138 | complex attribute is ugly. Instead, consider using |
e4a134ed |
139 | L<Moose::Meta::Attribute::Native> traits to define an API that exposes only |
140 | necessary pieces of functionality. |
541027c5 |
141 | |
053c63e0 |
142 | =head2 Always call C<inner> in the most specific subclass |
143 | |
144 | When using C<augment> and C<inner>, we recommend that you call |
145 | C<inner> in the most specific subclass of your hierarchy. This makes |
146 | it possible to subclass further and extend the hierarchy without |
147 | changing the parents. |
148 | |
d67ce58f |
149 | =head2 Namespace your types |
541027c5 |
150 | |
3bfacd05 |
151 | Use some sort of namespacing convention for type names. We recommend |
7b307c3e |
152 | something like "MyApp::Type::Foo". |
153 | |
154 | If you're intending to package your types up for re-use using |
289ea8f2 |
155 | L<MooseX::Types> later, avoid using characters that are invalid in |
156 | perl identifiers such as a space or period. |
541027c5 |
157 | |
1ad2aa8e |
158 | =head2 Do not coerce Moose built-ins directly |
159 | |
160 | If you define a coercion for a Moose built-in like C<ArrayRef>, this |
161 | will affect every application in the Perl interpreter that uses this |
162 | type. |
163 | |
164 | # very naughty! |
165 | coerce 'ArrayRef' |
166 | => from Str |
ff51bdc6 |
167 | => via { [ split /,/ ] }; |
1ad2aa8e |
168 | |
169 | Instead, create a subtype and coerce that: |
170 | |
e9be9f68 |
171 | subtype 'My::ArrayRef' => as 'ArrayRef'; |
1ad2aa8e |
172 | |
e9be9f68 |
173 | coerce 'My::ArrayRef' |
1ad2aa8e |
174 | => from 'Str' |
ff51bdc6 |
175 | => via { [ split /,/ ] }; |
1ad2aa8e |
176 | |
177 | =head2 Do not coerce class names directly |
178 | |
179 | Just as with Moose built-in types, a class type is global for the |
180 | entire interpreter. If you add a coercion for that class name, it can |
181 | have magical side effects elsewhere: |
182 | |
183 | # also very naughty! |
184 | coerce 'HTTP::Headers' |
185 | => from 'HashRef' |
ff51bdc6 |
186 | => via { HTTP::Headers->new( %{$_} ) }; |
1ad2aa8e |
187 | |
188 | Instead, we can create an "empty" subtype for the coercion: |
189 | |
e9be9f68 |
190 | subtype 'My::HTTP::Headers' => as class_type('HTTP::Headers'); |
1ad2aa8e |
191 | |
e9be9f68 |
192 | coerce 'My::HTTP::Headers' |
1ad2aa8e |
193 | => from 'HashRef' |
ff51bdc6 |
194 | => via { HTTP::Headers->new( %{$_} ) }; |
1ad2aa8e |
195 | |
196 | =head2 Use coercion instead of unions |
541027c5 |
197 | |
3bfacd05 |
198 | Consider using a type coercion instead of a type union. This was |
199 | covered at length in L<Moose::Manual::Types>. |
200 | |
d67ce58f |
201 | =head2 Define all your types in one module |
3bfacd05 |
202 | |
203 | Define all your types and coercions in one module. This was also |
204 | covered in L<Moose::Manual::Types>. |
205 | |
1ad2aa8e |
206 | =head1 BENEFITS OF BEST PRACTICES |
207 | |
208 | Following these practices has a number of benefits. |
209 | |
210 | It helps ensure that your code will play nice with others, making it |
211 | more reusable and easier to extend. |
212 | |
213 | Following an accepted set of idioms will make maintenance easier, |
214 | especially when someone else has to maintain your code. It will also |
215 | make it easier to get support from other Moose users, since your code |
216 | will be easier to digest quickly. |
217 | |
218 | Some of these practices are designed to help Moose do the right thing, |
219 | especially when it comes to immutabilization. This means your code |
220 | will be faster when immutabilized. |
221 | |
222 | Many of these practices also help get the most out of meta |
223 | programming. If you used an overridden C<new> to do type coercion by |
224 | hand, rather than defining a real coercion, there is no introspectable |
dab94063 |
225 | metadata. This sort of thing is particularly problematic for MooseX |
1ad2aa8e |
226 | extensions which rely on introspection to do the right thing. |
227 | |
3bfacd05 |
228 | =head1 AUTHOR |
229 | |
1ad2aa8e |
230 | Yuval (nothingmuch) Kogman |
231 | |
3bfacd05 |
232 | Dave Rolsky E<lt>autarch@urth.orgE<gt> |
233 | |
234 | =head1 COPYRIGHT AND LICENSE |
235 | |
2840a3b2 |
236 | Copyright 2009 by Infinity Interactive, Inc. |
3bfacd05 |
237 | |
238 | L<http://www.iinteractive.com> |
239 | |
240 | This library is free software; you can redistribute it and/or modify |
241 | it under the same terms as Perl itself. |
242 | |
243 | =cut |