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