Commit | Line | Data |
e67a0fca |
1 | |
2 | =pod |
3 | |
4 | =head1 NAME |
5 | |
4711f5f7 |
6 | Moose::Cookbook::FAQ - Frequently asked questions about Moose |
e67a0fca |
7 | |
8 | =head1 FREQUENTLY ASKED QUESTIONS |
9 | |
2a0f3bd3 |
10 | =head2 Module Stability |
11 | |
12 | =head3 Is Moose "production ready"? |
13 | |
004222dc |
14 | Yes. I have several medium-to-large-ish web applications in |
734d1752 |
15 | production using Moose, they have been running without |
004222dc |
16 | issue now for well over a year. |
734d1752 |
17 | |
004222dc |
18 | At C<$work> we are re-writing our core offering to use Moose, |
734d1752 |
19 | so it's continued development is assured. |
20 | |
21 | Several other people on #moose either have apps in production |
22 | which use Moose, or are in the process of deploying sites |
23 | which use Moose. |
2a0f3bd3 |
24 | |
25 | =head3 Is Moose's API stable? |
26 | |
27 | Yes and No. The external API, the one 90% of users will interact |
28 | with, is B<very stable> and any changes B<will be 100% backwards |
807f6b7c |
29 | compatible>. The introspection API is I<mostly> stable; I still |
2a0f3bd3 |
30 | reserve the right to tweak that if needed, but I will do my |
4711f5f7 |
31 | absolute best to maintain backwards compatibility here as well. |
2a0f3bd3 |
32 | |
734d1752 |
33 | =head3 I heard Moose is slow, is this true? |
2a0f3bd3 |
34 | |
35 | Again, this one is tricky, so Yes I<and> No. |
36 | |
37 | First let me say that I<nothing> in life is free, and that some |
38 | Moose features do cost more than others. It is also the |
39 | policy of Moose to B<only charge you for the features you use>, |
40 | and to do our absolute best to not place any extra burdens on |
d44714be |
41 | the execution of your code for features you are not using. Of |
42 | course using Moose itself does involve some overhead, but it |
43 | is mostly compile time. At this point we do have some options |
44 | available for getting the speed you need. |
2a0f3bd3 |
45 | |
734d1752 |
46 | Currently we have the option of making your classes immutable |
004222dc |
47 | as a means of boosting speed. This will mean a slightly larger compile |
734d1752 |
48 | time cost, but the runtime speed increase (especially in object |
4711f5f7 |
49 | construction) is pretty significant. This is not very well |
807f6b7c |
50 | documented yet, so please ask on the list or on #moose for more |
d44714be |
51 | information. |
52 | |
807f6b7c |
53 | We are also discussing and experimenting with L<Module::Compile>, |
54 | and the idea of compiling highly optimized C<.pmc> files. In |
55 | addition, we have mapped out some core methods as candidates for |
56 | conversion to XS. |
2a0f3bd3 |
57 | |
807f6b7c |
58 | =head3 When will Moose 1.0 be ready? |
2a0f3bd3 |
59 | |
004222dc |
60 | It is right now, I declared 0.18 to be "ready to use". |
2a0f3bd3 |
61 | |
e67a0fca |
62 | =head2 Constructors |
63 | |
64 | =head3 How do I write custom constructors with Moose? |
65 | |
66 | Ideally, you should never write your own C<new> method, and should |
67 | use Moose's other features to handle your specific object construction |
68 | needs. Here are a few scenarios, and the Moose way to solve them; |
69 | |
4711f5f7 |
70 | If you need to call initialization code post instance construction, |
e67a0fca |
71 | then use the C<BUILD> method. This feature is taken directly from |
4711f5f7 |
72 | Perl 6. Every C<BUILD> method in your inheritance chain is called |
e67a0fca |
73 | (in the correct order) immediately after the instance is constructed. |
74 | This allows you to ensure that all your superclasses are initialized |
75 | properly as well. This is the best approach to take (when possible) |
4711f5f7 |
76 | because it makes sub classing your class much easier. |
e67a0fca |
77 | |
78 | If you need to affect the constructor's parameters prior to the |
79 | instance actually being constructed, you have a number of options. |
80 | |
ce21ecc5 |
81 | To change the parameter processing as a whole, you can use |
82 | the C<BUILDARGS> method. The default implementation accepts key/value |
83 | pairs or a hash reference. You can override it to take positional args, |
84 | or any other format |
85 | |
86 | To change the handling of individual parameters, there are I<coercions> |
87 | (See the L<Moose::Cookbook::Recipe5> for a complete example and |
88 | explaination of coercions). With coercions it is possible to morph |
89 | argument values into the correct expected types. This approach is the |
90 | most flexible and robust, but does have a slightly higher learning |
91 | curve. |
e67a0fca |
92 | |
4711f5f7 |
93 | =head3 How do I make non-Moose constructors work with Moose? |
e67a0fca |
94 | |
e760b278 |
95 | Usually the correct approach to subclassing a non Moose class is |
96 | delegation. Moose makes this easy using the C<handles> keyword, |
97 | coercions, and C<lazy_build>, so subclassing is often not the |
98 | ideal route. |
99 | |
100 | That said, the default Moose constructors is inherited from |
101 | L<Moose::Object>. When inheriting from a non-Moose class, the |
102 | inheritance chain to L<Moose::Object> is broken. The simplest way |
103 | to fix this is to simply explicitly inherit from L<Moose::Object> |
104 | yourself. |
105 | |
106 | However, this does not always fix the issue of actually calling the Moose |
107 | constructor. Fortunately L<Class::MOP::Class/new_object>, the low level |
108 | constructor, accepts the special C<__INSTANCE__> parameter, allowing you to |
109 | instantiate your Moose attributes: |
e67a0fca |
110 | |
111 | package My::HTML::Template; |
112 | use Moose; |
113 | |
4711f5f7 |
114 | # explicit inheritance |
e67a0fca |
115 | extends 'HTML::Template', 'Moose::Object'; |
116 | |
117 | # explicit constructor |
118 | sub new { |
119 | my $class = shift; |
120 | # call HTML::Template's constructor |
121 | my $obj = $class->SUPER::new(@_); |
122 | return $class->meta->new_object( |
123 | # pass in the constructed object |
124 | # using the special key __INSTANCE__ |
e760b278 |
125 | __INSTANCE__ => $obj, |
126 | @_, # pass in the normal args |
e67a0fca |
127 | ); |
128 | } |
129 | |
807f6b7c |
130 | Of course, this only works if both your Moose class and the |
e67a0fca |
131 | inherited non-Moose class use the same instance type (typically |
e760b278 |
132 | HASH refs). |
133 | |
134 | Note that this doesn't call C<BUILDALL> automatically, you must do that |
135 | yourself. |
e67a0fca |
136 | |
137 | Other techniques can be used as well, such as creating the object |
138 | using C<Moose::Object::new>, but calling the inherited non-Moose |
4711f5f7 |
139 | class's initialization methods (if available). |
e67a0fca |
140 | |
807f6b7c |
141 | It is also entirely possible to just rely on HASH autovivification |
142 | to create the slots needed for Moose based attributes, although this |
143 | does restrict use of construction time attribute features somewhat. |
e67a0fca |
144 | |
145 | In short, there are several ways to go about this, it is best to |
146 | evaluate each case based on the class you wish to extend, and the |
147 | features you wish to employ. As always, both IRC and the mailing |
148 | list are great ways to get help finding the best approach. |
149 | |
150 | =head2 Accessors |
151 | |
152 | =head3 How do I tell Moose to use get/set accessors? |
153 | |
154 | The easiest way to accomplish this is to use the C<reader> and |
155 | C<writer> attribute options. Here is some example code: |
156 | |
157 | has 'bar' => ( |
158 | isa => 'Baz', |
159 | reader => 'get_bar', |
160 | writer => 'set_bar', |
161 | ); |
162 | |
163 | Moose will still take advantage of type constraints, triggers, etc. |
164 | when creating these methods. |
165 | |
807f6b7c |
166 | If you do not like this much typing, and wish it to be a default for |
167 | your class, please see L<Moose::Policy>, and more specifically |
168 | L<Moose::Policy::FollowPBP>. This will allow you to write: |
e67a0fca |
169 | |
170 | has 'bar' => ( |
171 | isa => 'Baz', |
172 | is => 'rw', |
173 | ); |
174 | |
807f6b7c |
175 | And have Moose create seperate C<get_bar> and C<set_bar> methods |
176 | instead of a single C<bar> method. |
e67a0fca |
177 | |
807f6b7c |
178 | NOTE: This B<cannot> be set globally in Moose, as that would break |
e67a0fca |
179 | other classes which are built with Moose. |
180 | |
181 | =head3 How can I get Moose to inflate/deflate values in the accessor? |
182 | |
183 | Well, the first question to ask is if you actually need both inflate |
184 | and deflate. |
185 | |
186 | If you only need to inflate, then I suggest using coercions. Here is |
807f6b7c |
187 | some basic sample code for inflating a L<DateTime> object: |
e67a0fca |
188 | |
189 | subtype 'DateTime' |
190 | => as 'Object' |
191 | => where { $_->isa('DateTime') }; |
192 | |
193 | coerce 'DateTime' |
194 | => from 'Str' |
195 | => via { DateTime::Format::MySQL->parse_datetime($_) }; |
196 | |
197 | has 'timestamp' => (is => 'rw', isa => 'DateTime', coerce => 1); |
198 | |
199 | This creates a custom subtype for L<DateTime> objects, then attaches |
200 | a coercion to that subtype. The C<timestamp> attribute is then told |
807f6b7c |
201 | to expect a C<DateTime> type, and to try to coerce it. When a C<Str> |
e67a0fca |
202 | type is given to the C<timestamp> accessor, it will attempt to |
203 | coerce the value into a C<DateTime> object using the code in found |
204 | in the C<via> block. |
205 | |
807f6b7c |
206 | For a more comprehensive example of using coercions, see the |
e67a0fca |
207 | L<Moose::Cookbook::Recipe5>. |
208 | |
209 | If you need to deflate your attribute, the current best practice is to |
210 | add an C<around> modifier to your accessor. Here is some example code: |
211 | |
212 | # a timestamp which stores as |
213 | # seconds from the epoch |
214 | has 'timestamp' => (is => 'rw', isa => 'Int'); |
215 | |
216 | around 'timestamp' => sub { |
217 | my $next = shift; |
218 | my ($self, $timestamp) = @_; |
219 | # assume we get a DateTime object ... |
220 | $next->($self, $timestamp->epoch); |
221 | }; |
222 | |
223 | It is also possible to do deflation using coercion, but this tends |
224 | to get quite complex and require many subtypes. An example of this |
225 | is outside the scope of this document, ask on #moose or send a mail |
226 | to the list. |
227 | |
228 | Still another option is to write a custom attribute metaclass, which |
229 | is also outside the scope of this document, but I would be happy to |
230 | explain it on #moose or the mailing list. |
231 | |
4711f5f7 |
232 | =head2 Method Modifiers |
e67a0fca |
233 | |
234 | =head3 How can I affect the values in C<@_> using C<before>? |
235 | |
807f6b7c |
236 | You can't, actually: C<before> only runs before the main method, |
237 | and it cannot easily affect the method's execution. What you want is |
e67a0fca |
238 | an C<around> method. |
239 | |
240 | =head3 Can I use C<before> to stop execution of a method? |
241 | |
242 | Yes, but only if you throw an exception. If this is too drastic a |
243 | measure then I suggest using C<around> instead. The C<around> method |
807f6b7c |
244 | modifier is the only modifier which can gracefully prevent execution |
e67a0fca |
245 | of the main method. Here is an example: |
246 | |
247 | around 'baz' => sub { |
248 | my $next = shift; |
249 | my ($self, %options) = @_; |
807f6b7c |
250 | unless ($options->{bar} eq 'foo') { |
251 | return 'bar'; |
e67a0fca |
252 | } |
807f6b7c |
253 | $next->($self, %options); |
e67a0fca |
254 | }; |
255 | |
256 | By choosing not to call the C<$next> method, you can stop the |
257 | execution of the main method. |
258 | |
259 | =head2 Type Constraints |
260 | |
261 | =head3 How can I have a custom error message for a type constraint? |
262 | |
807f6b7c |
263 | Use the C<message> option when building the subtype, like so: |
e67a0fca |
264 | |
265 | subtype 'NaturalLessThanTen' |
266 | => as 'Natural' |
267 | => where { $_ < 10 } |
268 | => message { "This number ($_) is not less than ten!" }; |
269 | |
270 | This will be called when a value fails to pass the C<NaturalLessThanTen> |
271 | constraint check. |
272 | |
807f6b7c |
273 | =head3 Can I turn off type constraint checking? |
734d1752 |
274 | |
275 | Not yet, but soon. This option will likely be coming in the next |
276 | release. |
277 | |
b36c8076 |
278 | =head2 Roles |
279 | |
280 | =head3 How do I get Moose to call BUILD in all my composed roles? |
281 | |
282 | See L<Moose::Cookbook::WTF> and specifically the B<How come BUILD |
283 | is not called for my composed roles?> question in the B<Roles> section. |
284 | |
e67a0fca |
285 | =head1 AUTHOR |
286 | |
287 | Stevan Little E<lt>stevan@iinteractive.comE<gt> |
288 | |
289 | =head1 COPYRIGHT AND LICENSE |
290 | |
778db3ac |
291 | Copyright 2006-2008 by Infinity Interactive, Inc. |
e67a0fca |
292 | |
293 | L<http://www.iinteractive.com> |
294 | |
295 | This library is free software; you can redistribute it and/or modify |
296 | it under the same terms as Perl itself. |
297 | |
e760b278 |
298 | =cut |