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