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