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 |
15 | L<Moose::Manual::MOP> docs. There are also several extensions recipes |
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 | |
1d9599cb |
26 | If you only look at one extension, it should be this one. It provides |
27 | the equivalent of delegation for all of Perl's native data types, such |
28 | as array reference, hash references, numbers, strings, etc. |
1d8f590f |
29 | |
30 | This lets you create I<much> cleaner and fluent APIs. |
31 | |
32 | package User; |
33 | |
34 | use Moose; |
35 | use MooseX::AttributeHelpers; |
36 | |
37 | has '_orders' => ( |
38 | metaclass => 'Collection::Array', |
39 | is => 'ro', |
40 | isa => 'ArrayRef', |
41 | default => sub { [] }, |
42 | provides => { |
43 | push => 'add_order', |
44 | shift => 'next_order', |
45 | elements => 'orders', |
46 | }, |
47 | ); |
48 | |
49 | Instead of directly exposing an array reference, we have three |
50 | well-named, easy to use methods. |
51 | |
d67ce58f |
52 | =head1 L<MooseX::StrictConstructor> |
1d8f590f |
53 | |
54 | By default, Moose lets you pass any old junk into a class's |
0c39debe |
55 | constructor. If you load L<MooseX::StrictConstructor>, your class will |
1d8f590f |
56 | throw an error if it sees something it doesn't recognize; |
57 | |
58 | package User; |
59 | |
60 | use Moose; |
61 | use MooseX::StrictConstructor; |
62 | |
63 | has 'name'; |
64 | has 'email'; |
65 | |
66 | User->new( name => 'Bob', emali => 'bob@example.com' ); |
67 | |
0c39debe |
68 | With L<MooseX::StrictConstructor>, that typo ("emali") will cause a |
1d9599cb |
69 | runtime error. With plain old Moose, the "emali" attribute would be |
70 | silently ignored. |
1d8f590f |
71 | |
d67ce58f |
72 | =head1 L<MooseX::Params::Validate> |
1d8f590f |
73 | |
0c39debe |
74 | We have high hopes for the future of L<MooseX::Method::Signatures> and |
75 | L<MooseX::Declare>. However, for now we recommend the decidedly more |
76 | clunky (but also faster and simpler) L<MooseX::Params::Validate>. This |
1d8f590f |
77 | module lets you apply Moose types and coercions to any method |
78 | arguments. |
79 | |
80 | package User; |
81 | |
82 | use Moose; |
83 | use MooseX::Params::Validate qw( validatep ); |
84 | |
85 | sub login { |
86 | my $self = shift; |
87 | my ($password) |
1d9599cb |
88 | = validated_list( \@_, password => { isa => 'Str', required => 1 } ); |
1d8f590f |
89 | |
90 | ... |
91 | } |
92 | |
d67ce58f |
93 | =head1 L<MooseX::Getopt> |
1d8f590f |
94 | |
95 | This is a role which adds a C<new_with_options> method to your |
96 | class. This is a constructor that takes the command line options and |
97 | uses them to populate attributes. |
98 | |
0f62a437 |
99 | This makes writing a command-line application as a module trivially |
1d8f590f |
100 | simple: |
101 | |
102 | package App::Foo; |
103 | |
104 | use Moose; |
105 | with 'MooseX::Getopt'; |
106 | |
107 | has 'input' => ( |
108 | is => 'ro', |
109 | isa => 'Str', |
110 | required => 1 |
111 | ); |
112 | |
113 | has 'output' => ( |
114 | is => 'ro', |
115 | isa => 'Str', |
116 | required => 1 |
117 | ); |
118 | |
119 | sub run { ... } |
120 | |
121 | Then in the script that gets run we have: |
122 | |
123 | use App::Foo; |
124 | |
125 | App::Foo->new_with_options->run; |
126 | |
1d9599cb |
127 | From the command line, someone can execute the script: |
128 | |
129 | foo@example> foo --input /path/to/input --output /path/to/output |
130 | |
d67ce58f |
131 | =head1 L<MooseX::Singleton> |
1d8f590f |
132 | |
133 | To be honest, using a singleton is often a hack, but it sure is a |
0c39debe |
134 | handy hack. L<MooseX::Singleton> lets you have a Moose class that's a |
1d8f590f |
135 | singleton: |
136 | |
137 | package Config; |
138 | |
139 | use MooseX::Singleton; # instead of Moose |
140 | |
141 | has 'cache_dir' => ( ... ); |
142 | |
143 | It's that simple. |
144 | |
145 | =head1 EXTENSIONS TO CONSIDER |
146 | |
1d9599cb |
147 | There are literally dozens of other extensions on CPAN. This is a list |
148 | of extensions that you might find useful, but we're not quite ready to |
149 | endorse just yet. |
1d8f590f |
150 | |
d67ce58f |
151 | =head2 L<MooseX::Declare> |
1d8f590f |
152 | |
153 | Extends Perl with Moose-based keywords using C<Devel::Declare>. Very |
154 | cool, but still new and experimental. |
155 | |
156 | class User { |
157 | |
158 | has 'name' => ( ... ); |
159 | has 'email' => ( ... ); |
160 | |
161 | method login (Str $password) { ... } |
162 | } |
163 | |
d67ce58f |
164 | =head2 L<MooseX::Types> |
1d8f590f |
165 | |
166 | This extension helps you build a type library for your application. It |
6549b0d1 |
167 | also lets you predeclare type names and use them as barewords. |
1d8f590f |
168 | |
169 | use MooseX::Types -declare => ['PosInt']; |
170 | use MooseX::Types::Moose 'Int'; |
171 | |
172 | subtype PositiveInt |
173 | => as Int, |
174 | => where { $_ > 0 } |
175 | => message {"Int is not larger than 0"}; |
176 | |
1d9599cb |
177 | One nice feature is that those bareword names are actually namespaced |
1d8f590f |
178 | in Moose's type registry, so multiple applications can use the same |
179 | bareword names, even if the type definitions differ. |
180 | |
d67ce58f |
181 | =head2 L<MooseX::Types::Structured> |
1d8f590f |
182 | |
0c39debe |
183 | This extension builds on top of L<MooseX::Types> to let you declare |
1d8f590f |
184 | complex data structure types. |
185 | |
186 | use MooseX::Types -declare => [ qw( Name Color ) ]; |
187 | use MooseX::Types::Moose qw(Str Int); |
188 | use MooseX::Types::Structured qw(Dict Tuple Optional); |
189 | |
190 | subtype Name |
191 | => as Dict[ first => Str, middle => Optional[Str], last => Str ]; |
192 | |
193 | subtype Color |
194 | => as Tuple[ Int, Int, Int, Optional[Int] ]; |
195 | |
196 | Of course, you could always use objects to represent these sorts of |
197 | things too. |
198 | |
d67ce58f |
199 | =head2 L<MooseX::ClassAttribute> |
1d8f590f |
200 | |
201 | This extension provides class attributes for Moose classes. The |
202 | declared class attributes are introspectable just like regular Moose |
203 | attributes. |
204 | |
205 | package User; |
206 | |
207 | use Moose; |
208 | use MooseX::ClassAttribute; |
209 | |
210 | has 'name' => ( ... ); |
211 | |
212 | class_has 'Cache' => ( ... ); |
213 | |
d67ce58f |
214 | =head2 L<MooseX::Daemonize> |
1d8f590f |
215 | |
216 | This is a role that provides a number of methods useful for creating a |
217 | daemon, including methods for starting and stopping, managing a PID |
218 | file, and signal handling. |
219 | |
d67ce58f |
220 | =head2 L<MooseX::Role::Parameterized> |
1d8f590f |
221 | |
222 | If you find yourself wanting a role that customizes itself for each |
223 | consumer, this is the tool for you. With this module, you can create a |
224 | role that accepts parameters and generates attributes, methods, etc on |
225 | a customized basis for each consumer. |
226 | |
d67ce58f |
227 | =head2 L<MooseX::POE> |
1d8f590f |
228 | |
229 | This is a small wrapper that ties together a Moose class with |
230 | C<POE::Session>, and gives you an C<event> sugar function to declare |
231 | event handlers. |
232 | |
d67ce58f |
233 | =head2 L<MooseX::FollowPBP> |
ddf2636a |
234 | |
235 | Automatically names all accessors I<Perl Best Practices>-style, |
1d9599cb |
236 | "get_size" and "set_size". |
ddf2636a |
237 | |
d67ce58f |
238 | =head2 L<MooseX::SemiAffordanceAccessor> |
ddf2636a |
239 | |
1d9599cb |
240 | Automatically names all accessors with an explicit set and implicit |
241 | get, "size" and "set_size". |
ddf2636a |
242 | |
1d8f590f |
243 | =head1 AUTHOR |
244 | |
245 | Dave Rolsky E<lt>autarch@urth.orgE<gt> |
246 | |
247 | =head1 COPYRIGHT AND LICENSE |
248 | |
2840a3b2 |
249 | Copyright 2009 by Infinity Interactive, Inc. |
1d8f590f |
250 | |
251 | L<http://www.iinteractive.com> |
252 | |
253 | This library is free software; you can redistribute it and/or modify |
254 | it under the same terms as Perl itself. |
255 | |
256 | =cut |