version bump for 0.9.4
[gitmo/Moo.git] / lib / Moo.pm
CommitLineData
b1eebd55 1package Moo;
6c74d087 2
3use strictures 1;
b1eebd55 4use Moo::_Utils;
6c74d087 5
d6276203 6our $VERSION = '0.009004'; # 0.9.4
6d71fae7 7$VERSION = eval $VERSION;
8
14f32032 9our %MAKERS;
10
6c74d087 11sub import {
12 my $target = caller;
a16d301e 13 my $class = shift;
de3d4906 14 strictures->import;
1ba11455 15 return if $MAKERS{$target}; # already exported into this package
6c74d087 16 *{_getglob("${target}::extends")} = sub {
fb5074f6 17 _load_module($_) for @_;
786e5ba0 18 # Can't do *{...} = \@_ or 5.10.0's mro.pm stops seeing @ISA
19 @{*{_getglob("${target}::ISA")}{ARRAY}} = @_;
6c74d087 20 };
21 *{_getglob("${target}::with")} = sub {
b1eebd55 22 require Moo::Role;
6c74d087 23 die "Only one role supported at a time by with" if @_ > 1;
369a4c50 24 Moo::Role->apply_role_to_package($target, $_[0]);
6c74d087 25 };
a16d301e 26 $MAKERS{$target} = {};
14f32032 27 *{_getglob("${target}::has")} = sub {
28 my ($name, %spec) = @_;
29 ($MAKERS{$target}{accessor} ||= do {
30 require Method::Generate::Accessor;
31 Method::Generate::Accessor->new
32 })->generate_method($target, $name, \%spec);
a16d301e 33 $class->_constructor_maker_for($target)
34 ->register_attribute_specs($name, \%spec);
14f32032 35 };
6c74d087 36 foreach my $type (qw(before after around)) {
37 *{_getglob "${target}::${type}"} = sub {
dccea57d 38 require Class::Method::Modifiers;
6c74d087 39 _install_modifier($target, $type, @_);
40 };
41 }
42 {
43 no strict 'refs';
44 @{"${target}::ISA"} = do {
b1eebd55 45 require Moo::Object; ('Moo::Object');
6c74d087 46 } unless @{"${target}::ISA"};
47 }
48}
49
a16d301e 50sub _constructor_maker_for {
51 my ($class, $target) = @_;
52 return unless $MAKERS{$target};
53 $MAKERS{$target}{constructor} ||= do {
54 require Method::Generate::Constructor;
de5c0e53 55 my $con;
56
57 # using the -last- entry in @ISA means that classes created by
58 # Role::Tiny as N roles + superclass will still get the attributes
59 # from the superclass via the ->register_attribute_specs call later
60
61 if (my $super = do { no strict 'refs'; ${"${target}::ISA"}[-1] }) {
62 $con = $MAKERS{$super}{constructor} if $MAKERS{$super};
63 }
64 my $moo_constructor = !!$con || do {
65 my $t_new = $target->can('new');
66 $t_new and $t_new == Moo::Object->can('new');
67 };
68 require Moo::_mro unless $moo_constructor;
a16d301e 69 Method::Generate::Constructor
70 ->new(
71 package => $target,
72 accessor_generator => do {
73 require Method::Generate::Accessor;
74 Method::Generate::Accessor->new;
de5c0e53 75 },
76 ($moo_constructor ? ()
77 : (construction_string => '$class->next::method(@_)'))
a16d301e 78 )
79 ->install_delayed
de5c0e53 80 ->register_attribute_specs(%{$con?$con->all_attribute_specs:{}})
a16d301e 81 }
82}
83
6c74d087 841;
8146585e 85
505f8b7a 86=head1 NAME
87
88Moo - Minimalist Object Orientation (with Moose compatiblity)
89
5ef50c4d 90=head1 WARNING WARNING WARNING
91
92This is a 0.9 release because we're fairly sure it works. For us. Until it's
93tested in the wild, we make no guarantees it also works for you.
94
95If this module does something unexpected, please submit a failing test.
96
97But if it eats your cat, sleeps with your boyfriend, or pushes grandma down
98the stairs to save her from the terrible secret of space, it's not our fault.
99
8146585e 100=head1 SYNOPSIS
101
102 package Cat::Food;
103
104 use Moo;
105 use Sub::Quote;
106
107 sub feed_lion {
108 my $self = shift;
109 my $amount = shift || 1;
110
111 $self->pounds( $self->pounds - $amount );
112 }
113
114 has taste => (
115 is => 'ro',
116 );
117
118 has brand => (
119 is => 'ro',
120 isa => sub {
121 die "Only SWEET-TREATZ supported!" unless $_[0] eq 'SWEET-TREATZ'
122 },
123);
124
125 has pounds => (
126 is => 'rw',
127 isa => quote_sub q{ die "$_[0] is too much cat food!" unless $_[0] < 15 },
128 );
129
130 1;
131
132and else where
133
134 my $full = Cat::Food->new(
135 taste => 'DELICIOUS.',
136 brand => 'SWEET-TREATZ',
137 pounds => 10,
138 );
139
140 $full->feed_lion;
141
142 say $full->pounds;
143
144=head1 DESCRIPTION
145
146This module is an extremely light-weight, high-performance L<Moose> replacement.
147It also avoids depending on any XS modules to allow simple deployments. The
148name C<Moo> is based on the idea that it provides almost -but not quite- two
149thirds of L<Moose>.
150
151Unlike C<Mouse> this module does not aim at full L<Moose> compatibility. See
152L</INCOMPATIBILITIES> for more details.
153
5d5bb71d 154=head1 WHY MOO EXISTS
155
156If you want a full object system with a rich Metaprotocol, L<Moose> is
157already wonderful.
158
159I've tried several times to use L<Mouse> but it's 3x the size of Moo and
160takes longer to load than most of my Moo based CGI scripts take to run.
161
162If you don't want L<Moose>, you don't want "less metaprotocol" like L<Mouse>,
163you want "as little as possible" - which means "no metaprotocol", which is
164what Moo provides.
165
166By Moo 1.0 I intend to have Moo's equivalent of L<Any::Moose> built in -
167if Moose gets loaded, any Moo class or role will act as a Moose equivalent
168if treated as such.
169
170Hence - Moo exists as its name - Minimal Object Orientation - with a pledge
171to make it smooth to upgrade to L<Moose> when you need more than minimal
172features.
173
8146585e 174=head1 IMPORTED METHODS
175
176=head2 new
177
178 Foo::Bar->new( attr1 => 3 );
179
180or
181
182 Foo::Bar->new({ attr1 => 3 });
183
2e575bcd 184=head2 BUILDARGS
185
186This feature from Moose is not yet supported.
187
8146585e 188=head2 BUILDALL
189
190Don't override (or probably even call) this method. Instead, you can define
191a C<BUILD> method on your class and the constructor will automatically call the
192C<BUILD> method from parent down to child after the object has been
193instantiated. Typically this is used for object validation or possibly logging.
194
195=head2 does
196
197 if ($foo->does('Some::Role1')) {
198 ...
199 }
200
201Returns true if the object composes in the passed role.
202
203=head1 IMPORTED SUBROUTINES
204
205=head2 extends
206
207 extends 'Parent::Class';
208
2e575bcd 209Declares base class. Multiple superclasses can be passed for multiple
210inheritance (but please use roles instead).
211
212Calling extends more than once will REPLACE your superclasses, not add to
213them like 'use base' would.
8146585e 214
215=head2 with
216
217 with 'Some::Role1';
218 with 'Some::Role2';
219
220Composes a L<Role::Tiny> into current class. Only one role may be composed in
221at a time to allow the code to remain as simple as possible.
222
223=head2 has
224
225 has attr => (
226 is => 'ro',
227 );
228
229Declares an attribute for the class.
230
231The options for C<has> are as follows:
232
233=over 2
234
235=item * is
236
237B<required>, must be C<ro> or C<rw>. Unsurprisingly, C<ro> generates an
0654a8fa 238accessor that will not respond to arguments; to be clear: a getter only. C<rw>
8146585e 239will create a perlish getter/setter.
240
241=item * isa
242
243Takes a coderef which is meant to validate the attribute. Unlike L<Moose> Moo
244does not include a basic type system, so instead of doing C<< isa => 'Num' >>,
245one should do
246
247 isa => quote_sub q{
248 die "$_[0] is not a number!" unless looks_like_number $_[0]
249 },
250
251L<Sub::Quote aware|/SUB QUOTE AWARE>
252
253=item * coerce
254
2e575bcd 255This Moose feature is not yet supported
256
257=begin hide
258
8146585e 259Takes a coderef which is meant to coerce the attribute. The basic idea is to
260do something like the following:
261
262 coerce => quote_sub q{
263 $_[0] + 1 unless $_[0] % 2
264 },
265
266L<Sub::Quote aware|/SUB QUOTE AWARE>
267
2e575bcd 268=end hide
269
8146585e 270=item * trigger
271
272Takes a coderef which will get called any time the attribute is set. Coderef
273will be invoked against the object with the new value as an argument.
274
2e575bcd 275Note that Moose also passes the old value, if any; this feature is not yet
276supported.
277
8146585e 278L<Sub::Quote aware|/SUB QUOTE AWARE>
279
280=item * default
281
2e575bcd 282Takes a coderef which will get called with $self as its only argument
283to populate an attribute if no value is supplied to the constructor - or
284if the attribute is lazy, when the attribute is first retrieved if no
285value has yet been provided.
286
287Note that if your default is fired during new() there is no guarantee that
288other attributes have been populated yet so you should not rely on their
289existence.
8146585e 290
291L<Sub::Quote aware|/SUB QUOTE AWARE>
292
293=item * predicate
294
2e575bcd 295Takes a method name which will return true if an attribute has a value.
8146585e 296
297A common example of this would be to call it C<has_$foo>, implying that the
298object has a C<$foo> set.
299
300=item * builder
301
2e575bcd 302Takes a method name which will be called to create the attribute - functions
303exactly like default except that instead of calling
304
305 $default->($self);
306
307Moo will call
308
309 $self->$builder;
8146585e 310
311=item * clearer
312
313Takes a method name which will clear the attribute.
314
315=item * lazy
316
317B<Boolean>. Set this if you want values for the attribute to be grabbed
318lazily. This is usually a good idea if you have a L</builder> which requires
319another attribute to be set.
320
321=item * required
322
323B<Boolean>. Set this if the attribute must be passed on instantiation.
324
325=item * weak_ref
326
327B<Boolean>. Set this if you want the reference that the attribute contains to
328be weakened; use this when circular references are possible, which will cause
329leaks.
330
331=item * init_arg
332
333Takes the name of the key to look for at instantiation time of the object. A
334common use of this is to make an underscored attribute have a non-underscored
335initialization name. C<undef> means that passing the value in on instantiation
336
337=back
338
339=head2 before
340
341 before foo => sub { ... };
342
343See L<< Class::Method::Modifiers/before method(s) => sub { ... } >> for full
344documentation.
345
346=head2 around
347
348 around foo => sub { ... };
349
350See L<< Class::Method::Modifiers/around method(s) => sub { ... } >> for full
351documentation.
352
353=head2 after
354
355 after foo => sub { ... };
356
357See L<< Class::Method::Modifiers/after method(s) => sub { ... } >> for full
358documentation.
359
8146585e 360=head1 SUB QUOTE AWARE
361
362L<Sub::Quote/quote_sub> allows us to create coderefs that are "inlineable,"
363giving us a handy, XS-free speed boost. Any option that is L<Sub::Quote>
364aware can take advantage of this.
365
2e575bcd 366=head1 INCOMPATIBILITIES WITH MOOSE
8146585e 367
368You can only compose one role at a time. If your application is large or
369complex enough to warrant complex composition, you wanted L<Moose>.
370
371There is no complex type system. C<isa> is verified with a coderef, if you
372need complex types, just make a library of coderefs, or better yet, functions
373that return quoted subs.
374
2e575bcd 375C<initializer> is not supported in core since the author considers it to be a
376bad idea but may be supported by an extension in future.
8146585e 377
378There is no meta object. If you need this level of complexity you wanted
2e575bcd 379L<Moose> - Moo succeeds at being small because it explicitly does not
380provide a metaprotocol.
8146585e 381
2e575bcd 382No support for C<super>, C<override>, C<inner>, or C<augment> - override can
383be handled by around albeit with a little more typing, and the author considers
384augment to be a bad idea.
8146585e 385
386L</default> only supports coderefs, because doing otherwise is usually a
387mistake anyway.
388
389C<lazy_build> is not supported per se, but of course it will work if you
390manually set all the options it implies.
391
2e575bcd 392C<auto_deref> is not supported since the author considers it a bad idea.
8146585e 393
2e575bcd 394C<documentation> is not supported since it's a very poor replacement for POD.