Commit | Line | Data |
e67a0fca |
1 | |
2 | =pod |
3 | |
4 | =head1 NAME |
5 | |
6 | Moose::Cookbook::FAQ - Frequenty asked questions about Moose |
7 | |
8 | =head1 FREQUENTLY ASKED QUESTIONS |
9 | |
2a0f3bd3 |
10 | =head2 Module Stability |
11 | |
12 | =head3 Is Moose "production ready"? |
13 | |
14 | Yes and No. Currently I have one web application in production |
15 | using Moose, and at $work we are re-writing our core offering to |
16 | use Moose. Several other people on #moose either have sites in |
17 | production which use Moose, or are in the process of deploying |
18 | sites which use Moose. |
19 | |
20 | The biggest barrier to widespread use of Moose in production |
21 | right now is speed of development and speed of execution. |
22 | |
23 | Since development is still happening, regular upgrades are a |
24 | fact of life. This can be hairy in production, so if this makes |
25 | you quake with fear, you might want to wait a few months. |
26 | |
ecb59493 |
27 | Then comes speed of execution. In some ways, Moose is actually |
28 | pretty fast and makes great effort to stay out of your way when |
29 | you don't want it there. However, certain parts of Moose are |
30 | slow, such as compile time setup, introspection and object |
31 | construction (only because it uses introspection). See |
32 | L<Is Moose slow?> below for a deeper discussion on the subject. |
2a0f3bd3 |
33 | |
34 | =head3 Is Moose's API stable? |
35 | |
36 | Yes and No. The external API, the one 90% of users will interact |
37 | with, is B<very stable> and any changes B<will be 100% backwards |
38 | compatible>. The introspection API is I<mostly> stable, I still |
39 | reserve the right to tweak that if needed, but I will do my |
40 | absolute best to maintain backwards comptability here as well. |
41 | |
42 | =head3 Is Moose slow? |
43 | |
44 | Again, this one is tricky, so Yes I<and> No. |
45 | |
46 | First let me say that I<nothing> in life is free, and that some |
47 | Moose features do cost more than others. It is also the |
48 | policy of Moose to B<only charge you for the features you use>, |
49 | and to do our absolute best to not place any extra burdens on |
50 | the execution of your code for features you are not using. |
51 | |
52 | Next, I will point out again that we are still in the "early |
53 | adopter" phase, so speed it not that important yet. We are |
54 | actually optimizing for "theoretical correctness" first, and |
55 | we will optimize for speed later. It has been our experience |
56 | that taking this approach allows for greater optimization |
57 | capacity. |
58 | |
59 | And lastly, I want to reassure the speed junkies out there that |
60 | we B<are> working on it. |
61 | |
62 | We have the immutable classes in Class::MOP, but which are not |
63 | yet integrated with Moose. These allow you to "close" a class |
64 | and then for many of it's more expensive methods to me memoized. |
65 | Our tests indicated a performance comparable (and in some |
66 | instances exceeding) that of hand-coded Perl. |
67 | |
68 | We are also discussing and experimenting with L<Module::Compile>, |
69 | and the idea of compiling highly optimized C<.pmc> files. And we |
70 | have also mapped out some core methods as canidates for conversion |
71 | to XS. |
72 | |
73 | =head3 When will Moose be 1.0 ready? |
74 | |
75 | I expect (barring unforseen circumstances) that Moose will be |
76 | at 1.0 by the end of this year (2006). Which means that it will be |
77 | completely stable and provide a number of optimization options to |
78 | suit the need for speed. |
79 | |
80 | Will I have addressed all your concerns by then? Will all the |
81 | features you want be included? I don't know unless you tell me, |
82 | so come over to #moose and we can talk. |
83 | |
e67a0fca |
84 | =head2 Constructors |
85 | |
86 | =head3 How do I write custom constructors with Moose? |
87 | |
88 | Ideally, you should never write your own C<new> method, and should |
89 | use Moose's other features to handle your specific object construction |
90 | needs. Here are a few scenarios, and the Moose way to solve them; |
91 | |
92 | If you need to call initializtion code post instance construction, |
93 | then use the C<BUILD> method. This feature is taken directly from |
94 | Perl 6. Every C<BUILD> method in your inheritence chain is called |
95 | (in the correct order) immediately after the instance is constructed. |
96 | This allows you to ensure that all your superclasses are initialized |
97 | properly as well. This is the best approach to take (when possible) |
98 | because it makes subclassing your class much easier. |
99 | |
100 | If you need to affect the constructor's parameters prior to the |
101 | instance actually being constructed, you have a number of options. |
102 | |
103 | First, there are I<coercions> (See the L<Moose::Cookbook::Recipe5> |
104 | for a complete example and explaination of coercions). With |
105 | coercions it is possible to morph argument values into the correct |
106 | expected types. This approach is the most flexible and robust, but |
107 | does have a slightly higher learning curve. |
108 | |
109 | Second, using an C<around> method modifier on C<new> can be an |
110 | effective way to affect the contents of C<@_> prior to letting |
111 | Moose deal with it. This carries with it the extra burden for |
112 | your subclasses, in that they have to be sure to explicitly |
113 | call your C<new> and/or work around your C<new> to get to the |
114 | version from L<Moose::Object>. |
115 | |
116 | The last approach is to use the standard Perl technique of calling |
117 | the C<SUPER::new> within your own custom version of C<new>. This |
118 | of course brings with it all the issues of the C<around> solution |
119 | along with any issues C<SUPER::> might add as well. |
120 | |
121 | In short, try to use C<BUILD> and coercions, they are your best |
122 | bets. |
123 | |
124 | =head3 How do I make non-Moose constuctors work with Moose? |
125 | |
126 | Moose provides it's own constructor, but it does it by making all |
127 | Moose-based classes inherit from L<Moose::Object>. When inheriting |
128 | from a non-Moose class, the inheritence chain to L<Moose::Object> |
129 | is broken. The simplest way to fix this is to simply explicitly |
130 | inherit from L<Moose::Object> yourself. However, this does not |
131 | always fix the issue of a constructor. Here is a basic example of |
132 | how this can be worked around: |
133 | |
134 | package My::HTML::Template; |
135 | use Moose; |
136 | |
137 | # explict inheritence |
138 | extends 'HTML::Template', 'Moose::Object'; |
139 | |
140 | # explicit constructor |
141 | sub new { |
142 | my $class = shift; |
143 | # call HTML::Template's constructor |
144 | my $obj = $class->SUPER::new(@_); |
145 | return $class->meta->new_object( |
146 | # pass in the constructed object |
147 | # using the special key __INSTANCE__ |
148 | __INSTANCE__ => $obj, @_ |
149 | ); |
150 | } |
151 | |
152 | Of course this only works if both your Moose class, and the |
153 | inherited non-Moose class use the same instance type (typically |
154 | HASH refs). |
155 | |
156 | Other techniques can be used as well, such as creating the object |
157 | using C<Moose::Object::new>, but calling the inherited non-Moose |
158 | class's initializtion methods (if available). |
159 | |
160 | It is also entirely possible to just rely on HASH autovivification |
161 | to create the slot's needed for Moose based attributes. Although |
162 | this does somewhat restrict use of construction time attribute |
163 | features. |
164 | |
165 | In short, there are several ways to go about this, it is best to |
166 | evaluate each case based on the class you wish to extend, and the |
167 | features you wish to employ. As always, both IRC and the mailing |
168 | list are great ways to get help finding the best approach. |
169 | |
170 | =head2 Accessors |
171 | |
172 | =head3 How do I tell Moose to use get/set accessors? |
173 | |
174 | The easiest way to accomplish this is to use the C<reader> and |
175 | C<writer> attribute options. Here is some example code: |
176 | |
177 | has 'bar' => ( |
178 | isa => 'Baz', |
179 | reader => 'get_bar', |
180 | writer => 'set_bar', |
181 | ); |
182 | |
183 | Moose will still take advantage of type constraints, triggers, etc. |
184 | when creating these methods. |
185 | |
186 | If you do not like this much typing, and wish it to be a default for |
187 | your class. Please see L<Moose::Policy>, and more specifically the |
188 | L<Moose::Policy::FollowPBP>. This will allow you to write this: |
189 | |
190 | has 'bar' => ( |
191 | isa => 'Baz', |
192 | is => 'rw', |
193 | ); |
194 | |
195 | And have Moose create C<get_bar> and C<set_bar> instead of the usual |
196 | C<bar>. |
197 | |
198 | NOTE: This B<cannot> be set globally in Moose, as this would break |
199 | other classes which are built with Moose. |
200 | |
201 | =head3 How can I get Moose to inflate/deflate values in the accessor? |
202 | |
203 | Well, the first question to ask is if you actually need both inflate |
204 | and deflate. |
205 | |
206 | If you only need to inflate, then I suggest using coercions. Here is |
207 | some basic sample code for inflating a L<DateTime> object. |
208 | |
209 | subtype 'DateTime' |
210 | => as 'Object' |
211 | => where { $_->isa('DateTime') }; |
212 | |
213 | coerce 'DateTime' |
214 | => from 'Str' |
215 | => via { DateTime::Format::MySQL->parse_datetime($_) }; |
216 | |
217 | has 'timestamp' => (is => 'rw', isa => 'DateTime', coerce => 1); |
218 | |
219 | This creates a custom subtype for L<DateTime> objects, then attaches |
220 | a coercion to that subtype. The C<timestamp> attribute is then told |
221 | to expect a C<DateTime> type, and to try and coerce it. When a C<Str> |
222 | type is given to the C<timestamp> accessor, it will attempt to |
223 | coerce the value into a C<DateTime> object using the code in found |
224 | in the C<via> block. |
225 | |
226 | For a more detailed and complete example of coercions, see the |
227 | L<Moose::Cookbook::Recipe5>. |
228 | |
229 | If you need to deflate your attribute, the current best practice is to |
230 | add an C<around> modifier to your accessor. Here is some example code: |
231 | |
232 | # a timestamp which stores as |
233 | # seconds from the epoch |
234 | has 'timestamp' => (is => 'rw', isa => 'Int'); |
235 | |
236 | around 'timestamp' => sub { |
237 | my $next = shift; |
238 | my ($self, $timestamp) = @_; |
239 | # assume we get a DateTime object ... |
240 | $next->($self, $timestamp->epoch); |
241 | }; |
242 | |
243 | It is also possible to do deflation using coercion, but this tends |
244 | to get quite complex and require many subtypes. An example of this |
245 | is outside the scope of this document, ask on #moose or send a mail |
246 | to the list. |
247 | |
248 | Still another option is to write a custom attribute metaclass, which |
249 | is also outside the scope of this document, but I would be happy to |
250 | explain it on #moose or the mailing list. |
251 | |
252 | =head2 Method Modfiers |
253 | |
254 | =head3 How can I affect the values in C<@_> using C<before>? |
255 | |
256 | You can't actually, C<before> only runs before the main method, |
257 | and it cannot easily affect the execution of it. What you want is |
258 | an C<around> method. |
259 | |
260 | =head3 Can I use C<before> to stop execution of a method? |
261 | |
262 | Yes, but only if you throw an exception. If this is too drastic a |
263 | measure then I suggest using C<around> instead. The C<around> method |
264 | modifier is the only modifier which can actually stop the execution |
265 | of the main method. Here is an example: |
266 | |
267 | around 'baz' => sub { |
268 | my $next = shift; |
269 | my ($self, %options) = @_; |
270 | if ($options{bar} eq 'foo') { |
271 | $next->($self, %options); |
272 | } |
273 | else { |
274 | return 'bar'; |
275 | } |
276 | }; |
277 | |
278 | By choosing not to call the C<$next> method, you can stop the |
279 | execution of the main method. |
280 | |
281 | =head2 Type Constraints |
282 | |
283 | =head3 How can I have a custom error message for a type constraint? |
284 | |
285 | Use the C<message> option when building the subtype. Like so: |
286 | |
287 | subtype 'NaturalLessThanTen' |
288 | => as 'Natural' |
289 | => where { $_ < 10 } |
290 | => message { "This number ($_) is not less than ten!" }; |
291 | |
292 | This will be called when a value fails to pass the C<NaturalLessThanTen> |
293 | constraint check. |
294 | |
295 | =head1 AUTHOR |
296 | |
297 | Stevan Little E<lt>stevan@iinteractive.comE<gt> |
298 | |
299 | =head1 COPYRIGHT AND LICENSE |
300 | |
301 | Copyright 2006 by Infinity Interactive, Inc. |
302 | |
303 | L<http://www.iinteractive.com> |
304 | |
305 | This library is free software; you can redistribute it and/or modify |
306 | it under the same terms as Perl itself. |
307 | |
308 | =cut |