Commit | Line | Data |
1d8f590f |
1 | =pod |
2 | |
3 | =head1 NAME |
4 | |
d67ce58f |
5 | Moose::Manual::MooseX - Recommended Moose extensions |
1d8f590f |
6 | |
7 | =head1 MooseX? |
8 | |
1d9599cb |
9 | It's easy to extend and change Moose, and this is part of what makes |
10 | Moose so powerful. You can use the MOP API to do things your own way, |
1d8f590f |
11 | add new features, and generally customize your Moose. |
12 | |
13 | Writing your own extensions does require a good understanding of the |
1d9599cb |
14 | meta-model. You can start learning about this with the |
dab94063 |
15 | L<Moose::Manual::MOP> docs. There are also several extension recipes |
1d9599cb |
16 | in the L<Moose::Cookbook>. |
1d8f590f |
17 | |
18 | Explaining how to write extensions is beyond the scope of this |
19 | manual. Fortunately, lots of people have already written extensions |
20 | and put them on CPAN for you. |
21 | |
22 | This document covers a few of the ones we like best. |
23 | |
d67ce58f |
24 | =head1 L<MooseX::AttributeHelpers> |
1d8f590f |
25 | |
e4a134ed |
26 | The functionality of this MooseX module has been moved into Moose core. |
27 | See L<Moose::Meta::Attribute::Native>. |
1d8f590f |
28 | |
a434262f |
29 | =head1 L<Moose::Autobox> |
30 | |
31 | MooseX::AttributeHelpers, but turned inside out, Moose::Autobox provides |
32 | methods on both arrays/hashes/etc. but also references to them, using |
33 | Moose roles, allowing you do to things like: |
34 | |
35 | use Moose::Autobox; |
36 | |
37 | $somebody_elses_object->orders->push($order); |
38 | |
39 | Lexically scoped and not to everybody's taste, but very handy for sugaring |
40 | up other people's APIs and your own code. |
41 | |
d67ce58f |
42 | =head1 L<MooseX::StrictConstructor> |
1d8f590f |
43 | |
44 | By default, Moose lets you pass any old junk into a class's |
0c39debe |
45 | constructor. If you load L<MooseX::StrictConstructor>, your class will |
1d8f590f |
46 | throw an error if it sees something it doesn't recognize; |
47 | |
48 | package User; |
49 | |
50 | use Moose; |
51 | use MooseX::StrictConstructor; |
52 | |
53 | has 'name'; |
54 | has 'email'; |
55 | |
56 | User->new( name => 'Bob', emali => 'bob@example.com' ); |
57 | |
0c39debe |
58 | With L<MooseX::StrictConstructor>, that typo ("emali") will cause a |
1d9599cb |
59 | runtime error. With plain old Moose, the "emali" attribute would be |
60 | silently ignored. |
1d8f590f |
61 | |
d67ce58f |
62 | =head1 L<MooseX::Params::Validate> |
1d8f590f |
63 | |
0c39debe |
64 | We have high hopes for the future of L<MooseX::Method::Signatures> and |
a434262f |
65 | L<MooseX::Declare>. However, these modules, while used regularly in |
66 | production by some of the more insane members of the community, are |
67 | still marked alpha just in case backwards incompatible changes need to |
68 | be made. |
69 | |
70 | If you don't want to risk that, for now we recommend the decidedly more |
0c39debe |
71 | clunky (but also faster and simpler) L<MooseX::Params::Validate>. This |
1d8f590f |
72 | module lets you apply Moose types and coercions to any method |
73 | arguments. |
74 | |
75 | package User; |
76 | |
77 | use Moose; |
5a3fb5fc |
78 | use MooseX::Params::Validate; |
1d8f590f |
79 | |
80 | sub login { |
81 | my $self = shift; |
82 | my ($password) |
1d9599cb |
83 | = validated_list( \@_, password => { isa => 'Str', required => 1 } ); |
1d8f590f |
84 | |
85 | ... |
86 | } |
87 | |
d67ce58f |
88 | =head1 L<MooseX::Getopt> |
1d8f590f |
89 | |
90 | This is a role which adds a C<new_with_options> method to your |
91 | class. This is a constructor that takes the command line options and |
92 | uses them to populate attributes. |
93 | |
0f62a437 |
94 | This makes writing a command-line application as a module trivially |
1d8f590f |
95 | simple: |
96 | |
97 | package App::Foo; |
98 | |
99 | use Moose; |
100 | with 'MooseX::Getopt'; |
101 | |
102 | has 'input' => ( |
103 | is => 'ro', |
104 | isa => 'Str', |
105 | required => 1 |
106 | ); |
107 | |
108 | has 'output' => ( |
109 | is => 'ro', |
110 | isa => 'Str', |
111 | required => 1 |
112 | ); |
113 | |
114 | sub run { ... } |
115 | |
116 | Then in the script that gets run we have: |
117 | |
118 | use App::Foo; |
119 | |
120 | App::Foo->new_with_options->run; |
121 | |
1d9599cb |
122 | From the command line, someone can execute the script: |
123 | |
124 | foo@example> foo --input /path/to/input --output /path/to/output |
125 | |
d67ce58f |
126 | =head1 L<MooseX::Singleton> |
1d8f590f |
127 | |
a434262f |
128 | To be honest, using a singleton is just a way to have a magic global |
129 | variable in languages that don't actually have global variables. |
130 | |
e24c59ad |
131 | In perl, you can just as easily use a global. However, if your |
132 | colleagues are Java-infected, they might prefer a singleton. Also, if |
133 | you have an existing class that I<isn't> a singleton but should be, |
134 | using L<MooseX::Singleton> is the easiest way to convert it. |
1d8f590f |
135 | |
136 | package Config; |
137 | |
138 | use MooseX::Singleton; # instead of Moose |
139 | |
140 | has 'cache_dir' => ( ... ); |
141 | |
142 | It's that simple. |
143 | |
144 | =head1 EXTENSIONS TO CONSIDER |
145 | |
1d9599cb |
146 | There are literally dozens of other extensions on CPAN. This is a list |
147 | of extensions that you might find useful, but we're not quite ready to |
148 | endorse just yet. |
1d8f590f |
149 | |
d67ce58f |
150 | =head2 L<MooseX::Declare> |
1d8f590f |
151 | |
152 | Extends Perl with Moose-based keywords using C<Devel::Declare>. Very |
153 | cool, but still new and experimental. |
154 | |
155 | class User { |
156 | |
157 | has 'name' => ( ... ); |
158 | has 'email' => ( ... ); |
159 | |
160 | method login (Str $password) { ... } |
161 | } |
162 | |
d67ce58f |
163 | =head2 L<MooseX::Types> |
1d8f590f |
164 | |
165 | This extension helps you build a type library for your application. It |
6549b0d1 |
166 | also lets you predeclare type names and use them as barewords. |
1d8f590f |
167 | |
5a3fb5fc |
168 | use MooseX::Types -declare => ['PositiveInt']; |
1d8f590f |
169 | use MooseX::Types::Moose 'Int'; |
170 | |
32a1dc89 |
171 | subtype PositiveInt, |
172 | as Int, |
173 | where { $_ > 0 }, |
174 | message { "Int is not larger than 0" }; |
1d8f590f |
175 | |
1d9599cb |
176 | One nice feature is that those bareword names are actually namespaced |
1d8f590f |
177 | in Moose's type registry, so multiple applications can use the same |
178 | bareword names, even if the type definitions differ. |
179 | |
d67ce58f |
180 | =head2 L<MooseX::Types::Structured> |
1d8f590f |
181 | |
0c39debe |
182 | This extension builds on top of L<MooseX::Types> to let you declare |
1d8f590f |
183 | complex data structure types. |
184 | |
185 | use MooseX::Types -declare => [ qw( Name Color ) ]; |
186 | use MooseX::Types::Moose qw(Str Int); |
187 | use MooseX::Types::Structured qw(Dict Tuple Optional); |
188 | |
189 | subtype Name |
190 | => as Dict[ first => Str, middle => Optional[Str], last => Str ]; |
191 | |
192 | subtype Color |
193 | => as Tuple[ Int, Int, Int, Optional[Int] ]; |
194 | |
195 | Of course, you could always use objects to represent these sorts of |
196 | things too. |
197 | |
d67ce58f |
198 | =head2 L<MooseX::ClassAttribute> |
1d8f590f |
199 | |
200 | This extension provides class attributes for Moose classes. The |
201 | declared class attributes are introspectable just like regular Moose |
202 | attributes. |
203 | |
204 | package User; |
205 | |
206 | use Moose; |
207 | use MooseX::ClassAttribute; |
208 | |
209 | has 'name' => ( ... ); |
210 | |
211 | class_has 'Cache' => ( ... ); |
212 | |
d6ed009f |
213 | Note however that this class attribute does I<not> inherit like a |
a434262f |
214 | L<Class::Data::Inheritable> or similar attribute - calling |
215 | |
216 | $subclass->Cache($cache); |
217 | |
218 | will set it for the superclass as well. Additionally, class data is usually |
219 | The Wrong Thing To Do in a strongly OO program since it makes testing a |
220 | lot harder - consider carefully whether you'd be better off with an object |
221 | that's passed around instead. |
222 | |
d67ce58f |
223 | =head2 L<MooseX::Daemonize> |
1d8f590f |
224 | |
225 | This is a role that provides a number of methods useful for creating a |
226 | daemon, including methods for starting and stopping, managing a PID |
227 | file, and signal handling. |
228 | |
d67ce58f |
229 | =head2 L<MooseX::Role::Parameterized> |
1d8f590f |
230 | |
231 | If you find yourself wanting a role that customizes itself for each |
232 | consumer, this is the tool for you. With this module, you can create a |
5a3fb5fc |
233 | role that accepts parameters and generates attributes, methods, etc. on |
1d8f590f |
234 | a customized basis for each consumer. |
235 | |
d67ce58f |
236 | =head2 L<MooseX::POE> |
1d8f590f |
237 | |
238 | This is a small wrapper that ties together a Moose class with |
239 | C<POE::Session>, and gives you an C<event> sugar function to declare |
240 | event handlers. |
241 | |
d67ce58f |
242 | =head2 L<MooseX::FollowPBP> |
ddf2636a |
243 | |
244 | Automatically names all accessors I<Perl Best Practices>-style, |
1d9599cb |
245 | "get_size" and "set_size". |
ddf2636a |
246 | |
d67ce58f |
247 | =head2 L<MooseX::SemiAffordanceAccessor> |
ddf2636a |
248 | |
1d9599cb |
249 | Automatically names all accessors with an explicit set and implicit |
250 | get, "size" and "set_size". |
ddf2636a |
251 | |
cc7dafef |
252 | =head2 L<MooseX::NonMoose> |
253 | |
254 | MooseX::NonMoose allows for easily subclassing non-Moose classes with Moose, |
255 | taking care of the annoying details connected with doing this, such as |
256 | setting up proper inheritance from Moose::Object and installing |
257 | (and inlining, at make_immutable time) a constructor that makes sure things |
258 | like BUILD methods are called. |
259 | |
1d8f590f |
260 | =head1 AUTHOR |
261 | |
262 | Dave Rolsky E<lt>autarch@urth.orgE<gt> |
263 | |
264 | =head1 COPYRIGHT AND LICENSE |
265 | |
2840a3b2 |
266 | Copyright 2009 by Infinity Interactive, Inc. |
1d8f590f |
267 | |
268 | L<http://www.iinteractive.com> |
269 | |
270 | This library is free software; you can redistribute it and/or modify |
271 | it under the same terms as Perl itself. |
272 | |
273 | =cut |