merge trunk to pluggable errors
[gitmo/Moose.git] / lib / Moose / Cookbook / Extending / Recipe1.pod
1
2 =pod
3
4 =head1 NAME
5
6 Moose::Cookbook::Extending::Recipe1 - Moose extension overview
7
8 =head1 DESCRIPTION
9
10 Moose has quite a number of ways in which extensions can hook into
11 Moose and change its behavior. Moose also has a lot of behavior that
12 can be changed. This recipe will provide an overview of each extension
13 method and give you some recommendations on what tools to use.
14
15 If you haven't yet read the recipes on metaclasses, go read those
16 first. You can't really write Moose extensions without understanding
17 the metaclasses, and those recipes also demonstrate some basic
18 extensions mechanisms such as metaclass subclasses and traits.
19
20 =head2 Playing Nice With Others
21
22 One of the goals of this overview is to help you build extensions that
23 cooperate well with other extensions. This is especially important if
24 you plan to release your extension to CPAN.
25
26 Moose comes with several modules that exist to help your write
27 cooperative extensions. These are L<Moose::Exporter> and
28 L<Moose::Util::MetaRole>. By using these two modules to implement your
29 extensions, you will ensure that your extension works with both the
30 Moose core features and any other CPAN extension using those modules.
31
32 =head1 PARTS OF Moose YOU CAN EXTEND
33
34 The types of things you might want to do in Moose extensions broadly
35 fall into a few categories.
36
37 =head2 Metaclass Extensions
38
39 One way of extending Moose is by extending one or more Moose
40 metaclasses. For example, in L<Moose::Cookbook::Meta::Recipe4> we saw
41 a metaclass subclass that added a C<table> attribute to the
42 metaclass. If you were writing an ORM, this would be a logical
43 extension.
44
45 Many of the Moose extensions on CPAN work by providing an attribute
46 metaclass extension. For example, the C<MooseX::AttributeHelpers>
47 distro provides a new attribute metaclass that lets you delegate
48 behavior to a non-object attribute (a hashref or simple number).
49
50 A metaclass extension can be packaged as a subclass or a
51 role/trait. If you can, we recommend using traits instead of
52 subclasses, since it's generally much easier to combine disparate
53 traits then it is to combine a bunch of subclasses.
54
55 When your extensions are implemented as roles, you can apply them with
56 the L<Moose::Util::MetaRole> module.
57
58 =head2 Providing Sugar Subs
59
60 As part of a metaclass extension, you may also want to provide some
61 sugar subroutines, much like C<Moose.pm> does. Moose provides a helper
62 module called L<Moose::Exporter> that makes this much simpler. This
63 will be used in several of the extension recipes.
64
65 =head2 Object Class Extensions
66
67 Another common Moose extension is to change the default object class
68 behavior. For example, the C<MooseX::Singleton> extension changes the
69 behavior of your objects so that they are singletons. The
70 C<MooseX::StrictConstructor> extension makes the constructor reject
71 arguments which don't match its attributes.
72
73 Object class extensions often also include metaclass extensions. In
74 particular, if you want your object extension to work when a class is
75 made immutable, you may need to extend some or all of the
76 C<Moose::Meta::Instance>, C<Moose::Meta::Method::Constructor>, and
77 C<Moose::Meta::Method::Destructor> objects.
78
79 The L<Moose::Util::MetaRole> module lets you apply roles to the base
80 object class, as well as the meta classes just mentioned.
81
82 =head2 Providing a Role
83
84 Some extensions come in the form of a role for you to consume. The
85 C<MooseX::Object::Pluggable> extension is a great example of this. In
86 fact, despite the C<MooseX> name, it does not actually change anything
87 about Moose's behavior. Instead, it is just a role that an object
88 which wants to be pluggable can consume.
89
90 If you are implementing this sort of extension, you don't need to do
91 anything special. You simply create a role and document that it should
92 be used via the normal C<with> sugar:
93
94    package RoleConsumer;
95
96    use Moose;
97
98    with 'MooseX::My::Role';
99
100 =head2 New Types
101
102 Another common Moose extension is a new type for the Moose type
103 system. In this case, you simply create a type in your module. When
104 people load your module, the type is created, and they can refer to it
105 by name after that. The C<MooseX::Types::URI> and
106 C<MooseX::Types::DateTime> distros are two good examples of how this
107 works.
108
109 =head1 ROLES VS TRAITS VS SUBCLASSES
110
111 It is important to understand that B<roles and traits are the same
112 thing>. A role can be used as a trait, and a trait is a role. The only
113 thing that distinguishes the two is that a trait is packaged in a way
114 that lets Moose resolve a short name to a class name. In other words,
115 with a trait, the caller can specify it by a short name like "Big",
116 and Moose will resolve it to a class like
117 C<MooseX::Embiggen::Meta::Attribute::Role::Big>.
118
119 See L<Moose::Cookbook::Meta::Recipe3> and
120 L<Moose::Cookbook::Meta::Recipe5> for examples of traits in action. In
121 particular, both of these recipes demonstrate the trait resolution
122 mechanism.
123
124 Implementing an extension as a (set of) metaclass or base object
125 role(s) will make your extension more cooperative. It is hard for an
126 end-user to effectively combine together multiple metaclass
127 subclasses, but it can be very easy to combine roles.
128
129 =head1 USING YOUR EXTENSION
130
131 There are a number of ways in which an extension can be applied. In
132 some cases you can provide multiple ways of consuming your extension.
133
134 =head2 Extensions as Metaclass Traits
135
136 If your extension is available as a trait, you can ask end users to
137 simply specify it in a list of traits. Currently, this only works for
138 metaclass and attribute metaclass traits:
139
140   use Moose -traits => [ 'Big', 'Blue' ];
141
142   has 'animal' =>
143      ( traits => [ 'Big', 'Blue' ],
144        ...
145      );
146
147 If your extension applies to any other metaclass, or the object base
148 class, you cannot use the trait mechanism.
149
150 The benefit of the trait mechanism is that is very easy to see where a
151 trait is applied in the code, and consumers have fine-grained control
152 over what the trait applies to. This is especially true for attribute
153 traits, where you can apply the trait to just one attribute in a
154 class.
155
156 =head2 Extensions as Metaclass (and Base Object) Subclasses
157
158 Moose does not provide any simple APIs for consumers to use a subclass
159 extension, except for attribute metaclasses. The attribute declaration
160 parameters include a C<metaclass> parameter a consumer of your
161 extension can use to specify your subclass.
162
163 This is one reason why implementing an extension as a subclass can be
164 a poor choice. However, you can force the use of certain subclasses at
165 import time by calling C<< Moose->init_meta >> for the caller, and
166 providing an alternate metaclass or base object class.
167
168 If you do want to do this, you should look at using C<Moose::Exporter>
169 to re-export the C<Moose.pm> sugar subroutines. When you use
170 L<Moose::Exporter> and your exporting class has an C<init_meta>
171 method, L<Moose::Exporter> makes sure that this C<init_meta> method
172 gets called when your class is imported.
173
174 Then in your C<init_meta> you can arrange for the caller to use your
175 subclasses:
176
177   package MooseX::Embiggen;
178
179   use Moose ();
180   use Moose::Exporter;
181
182   use MooseX::Embiggen::Meta::Class;
183   use MooseX::Embiggen::Object;
184
185   Moose::Exporter->setup_import_methods( also => 'Moose' );
186
187   sub init_meta {
188       shift; # just your package name
189       my %options = @_;
190
191       return Moose->init_meta(
192           for_class  => $options{for_class},
193           metaclass  => 'MooseX::Embiggen::Meta::Class',
194           base_class => 'MooseX::Embiggen::Object',
195       );
196   }
197
198 =head2 Extensions as Metaclass (and Base Object) Roles
199
200 Implementing your extensions as metaclass roles makes your extensions
201 easy to apply, and cooperative with other metaclass role-based extensions.
202
203 Just as with a subclass, you will probably want to package your
204 extensions for consumption with a single module that uses
205 L<Moose::Exporter>. However, in this case, you will use
206 L<Moose::Util::MetaRole> to apply all of your roles. The advantage of
207 using this module is that I<it preserves any subclassing or roles
208 already applied to the users metaclasses>. This means that your
209 extension is cooperative I<by default>, and consumers of your
210 extension can easily use it with other role-based extensions.
211
212   package MooseX::Embiggen;
213
214   use Moose ();
215   use Moose::Exporter;
216   use Moose::Util::MetaRole;
217
218   use MooseX::Embiggen::Role::Meta::Class;
219   use MooseX::Embiggen::Role::Meta::Attribute;
220   use MooseX::Embiggen::Role::Meta::Method::Constructor
221   use MooseX::Embiggen::Role::Object;
222
223   Moose::Exporter->setup_import_methods( also => 'Moose' );
224
225   sub init_meta {
226       shift; # just your package name
227       my %options = @_;
228
229       Moose->init_meta(%options);
230
231       my $meta = Moose::Util::MetaRole::apply_metaclass_roles(
232           for_class       => $options{for_class},
233           metaclass_roles => ['MooseX::Embiggen::Role::Meta::Class'],
234           attribute_metaclass_roles =>
235               ['MooseX::Embiggen::Role::Meta::Attribute'],
236           constructor_class_roles =>
237               ['MooseX::Embiggen::Role::Meta::Method::Constructor'],
238       );
239
240       Moose::Util::MetaRole::apply_base_class_roles(
241           for_class => $options{for_class},
242           roles     => ['MooseX::Embiggen::Role::Object'],
243       );
244
245       return $meta;
246   }
247
248 As you can see from this example, you can use C<Moose::Util::MetaRole>
249 to apply roles to any metaclass, as well as the base object class. If
250 some other extension has already applied its own roles, they will be
251 preserved when your extension applies its roles, and vice versa.
252
253 =head2 Providing Sugar
254
255 With L<Moose::Exporter>, you can also export your own sugar subs, as
256 well as those from other sugar modules:
257
258   package MooseX::Embiggen;
259
260   use Moose ();
261   use Moose::Exporter;
262
263   Moose::Exporter->setup_import_methods(
264       with_caller => ['embiggen'],
265       also        => 'Moose',
266   );
267
268   sub init_meta { ... }
269
270   sub embiggen {
271       my $caller = shift;
272       $caller->meta()->embiggen(@_);
273   }
274
275 And then the consumer of your extension can use your C<embiggen> sub:
276
277   package Consumer;
278
279   use MooseX::Embiggen;
280
281   extends 'Thing';
282
283   embiggen ...;
284
285 This can be combined with metaclass and base class roles quite easily.
286
287 =head1 LEGACY EXTENSION METHODOLOGIES
288
289 Before the existence of L<Moose::Exporter> and
290 L<Moose::Util::MetaRole>, there were a number of other ways to extend
291 Moose. In general, these methods were less cooperative, and only
292 worked well with a single extension.
293
294 These methods include C<metaclass.pm>, C<Moose::Policy> (which uses
295 C<metaclass.pm> under the hood), and various hacks to do what
296 L<Moose::Exporter> does. Please do not use these for your own
297 extensions.
298
299 Note that if you write a cooperative extension, it should cooperate
300 with older extensions, though older extensions generally do not
301 cooperate with each other.
302
303 =head1 CONCLUSION
304
305 If you can write your extension as one or more metaclass and base
306 object roles, please consider doing so. Make sure to read the docs for
307 L<Moose::Exporter> and L<Moose::Util::MetaRole> as well.
308
309 =head2 Caveat
310
311 The L<Moose::Util::MetaRole> API is still considered an experiment,
312 and could go away or change in the future.
313
314 =head1 AUTHOR
315
316 Dave Rolsky E<lt>autarch@urth.orgE<gt>
317
318 =head1 COPYRIGHT AND LICENSE
319
320 Copyright 2008 by Infinity Interactive, Inc.
321
322 L<http://www.iinteractive.com>
323
324 This library is free software; you can redistribute it and/or modify
325 it under the same terms as Perl itself.
326
327 =cut