Commit | Line | Data |
1d8f590f |
1 | =pod |
2 | |
3 | =head1 NAME |
4 | |
5 | Moose::Manual::MooseX - Recommended Moose Extensions |
6 | |
7 | =head1 MooseX? |
8 | |
9 | One of the great things about Moose is that it is easy to extend and |
10 | override. You can use the meta-model API to do things your own way, |
11 | add new features, and generally customize your Moose. |
12 | |
13 | Writing your own extensions does require a good understanding of the |
14 | meta-model. You can start learning about thiswith the |
15 | L<Moose::Manual::Introspection> docs. There are also several extensions |
16 | recipes in the L<Moose::Cookbook>. |
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 | |
24 | =head1 MooseX::AttributeHelpers |
25 | |
26 | If you only look at one extension, it should be this one. The name |
27 | isn't the best, but what it does it provide the equivalent of |
28 | delegation for all of Perl's native data types, such as array |
29 | reference, hash references, numbers, strings, etc. |
30 | |
31 | This lets you create I<much> cleaner and fluent APIs. |
32 | |
33 | package User; |
34 | |
35 | use Moose; |
36 | use MooseX::AttributeHelpers; |
37 | |
38 | has '_orders' => ( |
39 | metaclass => 'Collection::Array', |
40 | is => 'ro', |
41 | isa => 'ArrayRef', |
42 | default => sub { [] }, |
43 | provides => { |
44 | push => 'add_order', |
45 | shift => 'next_order', |
46 | elements => 'orders', |
47 | }, |
48 | ); |
49 | |
50 | Instead of directly exposing an array reference, we have three |
51 | well-named, easy to use methods. |
52 | |
53 | =head1 MooseX::StrictConstructor |
54 | |
55 | By default, Moose lets you pass any old junk into a class's |
56 | constructor. If you load C<MooseX::StrictConstructor>, your class will |
57 | throw an error if it sees something it doesn't recognize; |
58 | |
59 | package User; |
60 | |
61 | use Moose; |
62 | use MooseX::StrictConstructor; |
63 | |
64 | has 'name'; |
65 | has 'email'; |
66 | |
67 | User->new( name => 'Bob', emali => 'bob@example.com' ); |
68 | |
69 | With C<MooseX::StrictConstructor>, that typo ("emali") will cause a |
70 | runtime error. Otherwise, the "emali" attribute would just be silently |
71 | ignored. |
72 | |
73 | =head1 MooseX::Params::Validate |
74 | |
75 | We have high hopes for the future of C<MooseX::Method::Signatures> and |
76 | C<MooseX::Declare>. However, for now we recommend the decidely more |
77 | clunky (but also faster and simpler) C<MooseX::Params::Validate>. This |
78 | module lets you apply Moose types and coercions to any method |
79 | arguments. |
80 | |
81 | package User; |
82 | |
83 | use Moose; |
84 | use MooseX::Params::Validate qw( validatep ); |
85 | |
86 | sub login { |
87 | my $self = shift; |
88 | my ($password) |
89 | = validatep( \@_, password => { isa => 'Str', required => 1 } ); |
90 | |
91 | ... |
92 | } |
93 | |
94 | =head1 MooseX::Getopt |
95 | |
96 | This is a role which adds a C<new_with_options> method to your |
97 | class. This is a constructor that takes the command line options and |
98 | uses them to populate attributes. |
99 | |
100 | Thia makes writing a command-line application as a module trivially |
101 | simple: |
102 | |
103 | package App::Foo; |
104 | |
105 | use Moose; |
106 | with 'MooseX::Getopt'; |
107 | |
108 | has 'input' => ( |
109 | is => 'ro', |
110 | isa => 'Str', |
111 | required => 1 |
112 | ); |
113 | |
114 | has 'output' => ( |
115 | is => 'ro', |
116 | isa => 'Str', |
117 | required => 1 |
118 | ); |
119 | |
120 | sub run { ... } |
121 | |
122 | Then in the script that gets run we have: |
123 | |
124 | use App::Foo; |
125 | |
126 | App::Foo->new_with_options->run; |
127 | |
128 | =head1 MooseX::Singleton |
129 | |
130 | To be honest, using a singleton is often a hack, but it sure is a |
131 | handy hack. C<MooseX::Singleton> lets you have a Moose class that's a |
132 | singleton: |
133 | |
134 | package Config; |
135 | |
136 | use MooseX::Singleton; # instead of Moose |
137 | |
138 | has 'cache_dir' => ( ... ); |
139 | |
140 | It's that simple. |
141 | |
142 | =head1 EXTENSIONS TO CONSIDER |
143 | |
144 | There are literally dozens of other extensions on CPAN. These are a |
145 | few to consider. We're not quite ready to recommend them outright, |
146 | though. There's a couple reasons for this. One, they may be very |
147 | specialized. Two, they may be immature. Three, they may not be quite |
148 | right yet. Four, we may not all agree they're such a great idea. |
149 | |
150 | =head2 MooseX::Declare |
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 | |
163 | =head2 MooseX::Types |
164 | |
165 | This extension helps you build a type library for your application. It |
166 | also lets you pre-declare type names and use them as barewords. |
167 | |
168 | use MooseX::Types -declare => ['PosInt']; |
169 | use MooseX::Types::Moose 'Int'; |
170 | |
171 | subtype PositiveInt |
172 | => as Int, |
173 | => where { $_ > 0 } |
174 | => message {"Int is not larger than 0"}; |
175 | |
176 | One nice feature is the those bareword names are actually namespaces |
177 | in Moose's type registry, so multiple applications can use the same |
178 | bareword names, even if the type definitions differ. |
179 | |
180 | =head2 MooseX::Types::Structured |
181 | |
182 | This extension builds on top of C<MooseX::Types> to let you declare |
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 | |
198 | =head2 MooseX::ClassAttribute |
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 | |
213 | =head2 MooseX::Daemonize |
214 | |
215 | This is a role that provides a number of methods useful for creating a |
216 | daemon, including methods for starting and stopping, managing a PID |
217 | file, and signal handling. |
218 | |
219 | =head2 MooseX::Role::Parameterized |
220 | |
221 | If you find yourself wanting a role that customizes itself for each |
222 | consumer, this is the tool for you. With this module, you can create a |
223 | role that accepts parameters and generates attributes, methods, etc on |
224 | a customized basis for each consumer. |
225 | |
226 | =head2 MooseX::POE |
227 | |
228 | This is a small wrapper that ties together a Moose class with |
229 | C<POE::Session>, and gives you an C<event> sugar function to declare |
230 | event handlers. |
231 | |
ddf2636a |
232 | =head2 MooseX::FollowPBP |
233 | |
234 | Automatically names all accessors I<Perl Best Practices>-style, |
235 | "get_name" and "set_name". |
236 | |
237 | =head2 MooseX::SemiAffordanceAccessor |
238 | |
239 | Autoamtically names all accessors with an explicit set and implicit |
240 | get, "name" and "set_name". |
241 | |
1d8f590f |
242 | =head1 AUTHOR |
243 | |
244 | Dave Rolsky E<lt>autarch@urth.orgE<gt> |
245 | |
246 | =head1 COPYRIGHT AND LICENSE |
247 | |
2840a3b2 |
248 | Copyright 2009 by Infinity Interactive, Inc. |
1d8f590f |
249 | |
250 | L<http://www.iinteractive.com> |
251 | |
252 | This library is free software; you can redistribute it and/or modify |
253 | it under the same terms as Perl itself. |
254 | |
255 | =cut |