doc cleanup
[gitmo/Moo.git] / lib / Moo.pm
CommitLineData
b1eebd55 1package Moo;
6c74d087 2
3use strictures 1;
b1eebd55 4use Moo::_Utils;
e0e12d16 5use B 'perlstring';
a41e15c3 6use Sub::Defer ();
6c74d087 7
86e043d2 8our $VERSION = '0.091014'; # 0.91.14
6d71fae7 9$VERSION = eval $VERSION;
10
c2cb1fed 11require Moo::sification;
8c46a8f6 12
14f32032 13our %MAKERS;
14
108f8ddc 15sub _install_tracked {
16 my ($target, $name, $code) = @_;
17 $MAKERS{$target}{exports}{$name} = $code;
18 _install_coderef "${target}::${name}" => "Moo::${name}" => $code;
19}
20
6c74d087 21sub import {
22 my $target = caller;
a16d301e 23 my $class = shift;
de3d4906 24 strictures->import;
1ba11455 25 return if $MAKERS{$target}; # already exported into this package
108f8ddc 26 $MAKERS{$target} = {};
27 _install_tracked $target => extends => sub {
48a51428 28 $class->_set_superclasses($target, @_);
6c49212f 29 $class->_maybe_reset_handlemoose($target);
3d49ee27 30 return;
6c74d087 31 };
108f8ddc 32 _install_tracked $target => with => sub {
faa9ce11 33 require Moo::Role;
6067158c 34 Moo::Role->apply_roles_to_package($target, @_);
6c49212f 35 $class->_maybe_reset_handlemoose($target);
6c74d087 36 };
108f8ddc 37 _install_tracked $target => has => sub {
14f32032 38 my ($name, %spec) = @_;
a16d301e 39 $class->_constructor_maker_for($target)
40 ->register_attribute_specs($name, \%spec);
02e9ef74 41 $class->_accessor_maker_for($target)
42 ->generate_method($target, $name, \%spec);
6c49212f 43 $class->_maybe_reset_handlemoose($target);
3d49ee27 44 return;
14f32032 45 };
6c74d087 46 foreach my $type (qw(before after around)) {
108f8ddc 47 _install_tracked $target => $type => sub {
faa9ce11 48 require Class::Method::Modifiers;
6c74d087 49 _install_modifier($target, $type, @_);
3d49ee27 50 return;
6c74d087 51 };
52 }
53 {
54 no strict 'refs';
55 @{"${target}::ISA"} = do {
faa9ce11 56 require Moo::Object; ('Moo::Object');
6c74d087 57 } unless @{"${target}::ISA"};
58 }
3362e41c 59 if ($INC{'Moo/HandleMoose.pm'}) {
60 Moo::HandleMoose::inject_fake_metaclass_for($target);
61 }
6c74d087 62}
63
108f8ddc 64sub unimport {
65 my $target = caller;
66 _unimport_coderefs($target, $MAKERS{$target});
67}
68
48a51428 69sub _set_superclasses {
88aaa04a 70 my $class = shift;
71 my $target = shift;
72 for (@_) {
73 _load_module($_);
74 if ($INC{"Role/Tiny.pm"} && $Role::Tiny::INFO{$_}) {
75 require Carp;
76 Carp::croak("Can't extend role '$_'");
48a51428 77 }
88aaa04a 78 }
79 # Can't do *{...} = \@_ or 5.10.0's mro.pm stops seeing @ISA
80 @{*{_getglob("${target}::ISA")}{ARRAY}} = @_;
81 if (my $old = delete $Moo::MAKERS{$target}{constructor}) {
82 delete _getstash($target)->{new};
83 Moo->_constructor_maker_for($target)
84 ->register_attribute_specs(%{$old->all_attribute_specs});
85 }
86 no warnings 'once'; # piss off. -- mst
87 $Moo::HandleMoose::MOUSE{$target} = [
88 grep defined, map Mouse::Util::find_meta($_), @_
89 ] if $INC{"Mouse.pm"};
48a51428 90}
91
6c49212f 92sub _maybe_reset_handlemoose {
93 my ($class, $target) = @_;
94 if ($INC{"Moo/HandleMoose.pm"}) {
95 Moo::HandleMoose::maybe_reinject_fake_metaclass_for($target);
96 }
97}
98
02e9ef74 99sub _accessor_maker_for {
100 my ($class, $target) = @_;
101 return unless $MAKERS{$target};
102 $MAKERS{$target}{accessor} ||= do {
103 my $maker_class = do {
104 if (my $m = do {
105 if (my $defer_target =
106 (Sub::Defer::defer_info($target->can('new'))||[])->[0]
107 ) {
108 my ($pkg) = ($defer_target =~ /^(.*)::[^:]+$/);
109 $MAKERS{$pkg} && $MAKERS{$pkg}{accessor};
110 } else {
111 undef;
112 }
113 }) {
114 ref($m);
115 } else {
116 require Method::Generate::Accessor;
117 'Method::Generate::Accessor'
118 }
119 };
120 $maker_class->new;
121 }
122}
123
a16d301e 124sub _constructor_maker_for {
c4570291 125 my ($class, $target, $select_super) = @_;
a16d301e 126 return unless $MAKERS{$target};
127 $MAKERS{$target}{constructor} ||= do {
faa9ce11 128 require Method::Generate::Constructor;
129 require Sub::Defer;
c4570291 130 my ($moo_constructor, $con);
de5c0e53 131
c4570291 132 if ($select_super && $MAKERS{$select_super}) {
133 $moo_constructor = 1;
134 $con = $MAKERS{$select_super}{constructor};
135 } else {
de5c0e53 136 my $t_new = $target->can('new');
c4570291 137 if ($t_new) {
138 if ($t_new == Moo::Object->can('new')) {
139 $moo_constructor = 1;
140 } elsif (my $defer_target = (Sub::Defer::defer_info($t_new)||[])->[0]) {
141 my ($pkg) = ($defer_target =~ /^(.*)::[^:]+$/);
142 if ($MAKERS{$pkg}) {
143 $moo_constructor = 1;
144 $con = $MAKERS{$pkg}{constructor};
145 }
146 }
147 } else {
148 $moo_constructor = 1; # no other constructor, make a Moo one
149 }
de5c0e53 150 };
02e9ef74 151 ($con ? ref($con) : 'Method::Generate::Constructor')
a16d301e 152 ->new(
153 package => $target,
02e9ef74 154 accessor_generator => $class->_accessor_maker_for($target),
53875e2c 155 construction_string => (
156 $moo_constructor
157 ? ($con ? $con->construction_string : undef)
158 : ('$class->'.$target.'::SUPER::new(@_)')
e0e12d16 159 ),
76ab3977 160 subconstructor_handler => (
161 ' if ($Moo::MAKERS{$class}) {'."\n"
162 .' '.$class.'->_constructor_maker_for($class,'.perlstring($target).');'."\n"
163 .' return $class->new(@_)'.";\n"
346177ba 164 .' } elsif ($INC{"Moose.pm"} and my $meta = Class::MOP::get_metaclass_by_name($class)) {'."\n"
165 .' return $meta->new_object(@_);'."\n"
76ab3977 166 .' }'."\n"
e0e12d16 167 ),
a16d301e 168 )
169 ->install_delayed
de5c0e53 170 ->register_attribute_specs(%{$con?$con->all_attribute_specs:{}})
a16d301e 171 }
172}
173
6c74d087 1741;
a17be455 175=pod
176
177=encoding utf-8
8146585e 178
505f8b7a 179=head1 NAME
180
181Moo - Minimalist Object Orientation (with Moose compatiblity)
182
8146585e 183=head1 SYNOPSIS
184
185 package Cat::Food;
186
187 use Moo;
188 use Sub::Quote;
189
190 sub feed_lion {
191 my $self = shift;
192 my $amount = shift || 1;
193
194 $self->pounds( $self->pounds - $amount );
195 }
196
197 has taste => (
198 is => 'ro',
199 );
200
201 has brand => (
202 is => 'ro',
203 isa => sub {
204 die "Only SWEET-TREATZ supported!" unless $_[0] eq 'SWEET-TREATZ'
205 },
206);
207
208 has pounds => (
209 is => 'rw',
210 isa => quote_sub q{ die "$_[0] is too much cat food!" unless $_[0] < 15 },
211 );
212
213 1;
214
215and else where
216
217 my $full = Cat::Food->new(
218 taste => 'DELICIOUS.',
219 brand => 'SWEET-TREATZ',
220 pounds => 10,
221 );
222
223 $full->feed_lion;
224
225 say $full->pounds;
226
227=head1 DESCRIPTION
228
71bd6a81 229This module is an extremely light-weight subset of L<Moose> optimised for
230rapid startup and pay for what you use.
231
8146585e 232It also avoids depending on any XS modules to allow simple deployments. The
233name C<Moo> is based on the idea that it provides almost -but not quite- two
234thirds of L<Moose>.
235
71bd6a81 236Unlike C<Mouse> this module does not aim at full compatibility with
237L<Moose>'s surface syntax, preferring instead of provide full interoperability
238via the metaclass inflation capabilites described in L</MOO AND MOOSE>.
239
240For a full list of the minor differences between L<Moose> and L<Moo>'s surface
241syntax, see L</INCOMPATIBILITIES>.
8146585e 242
5d5bb71d 243=head1 WHY MOO EXISTS
244
245If you want a full object system with a rich Metaprotocol, L<Moose> is
246already wonderful.
247
71bd6a81 248However, sometimes you're writing a command line script or a CGI script
249where fast startup is essential, or code designed to be deployed as a single
250file via L<App::FatPacker>, or you're writing a CPAN module and you want it
251to be usable by people with those constraints.
252
5d5bb71d 253I've tried several times to use L<Mouse> but it's 3x the size of Moo and
254takes longer to load than most of my Moo based CGI scripts take to run.
255
256If you don't want L<Moose>, you don't want "less metaprotocol" like L<Mouse>,
257you want "as little as possible" - which means "no metaprotocol", which is
258what Moo provides.
259
71bd6a81 260Better still, if you install and load L<Moose>, we set up metaclasses for your
261L<Moo> classes and L<Moo::Role> roles, so you can use them in L<Moose> code
262without ever noticing that some of your codebase is using L<Moo>.
5d5bb71d 263
264Hence - Moo exists as its name - Minimal Object Orientation - with a pledge
265to make it smooth to upgrade to L<Moose> when you need more than minimal
266features.
267
71bd6a81 268=head1 MOO AND MOOSE
1fce5bc9 269
270If L<Moo> detects L<Moose> being loaded, it will automatically register
271metaclasses for your L<Moo> and L<Moo::Role> packages, so you should be able
a297a9ab 272to use them in L<Moose> code without anybody ever noticing you aren't using
1fce5bc9 273L<Moose> everywhere.
274
a297a9ab 275Extending a L<Moose> class or consuming a L<Moose::Role> will also work.
1fce5bc9 276
a297a9ab 277So will extending a L<Mouse> class or consuming a L<Mouse::Role> - but note
278that we don't provide L<Mouse> metaclasses or metaroles so the other way
279around doesn't work. This feature exists for L<Any::Moose> users porting to
280L<Moo>, enabling L<Mouse> users to use L<Moo> classes is not a priority for us.
c100c04c 281
660f3db2 282This means that there is no need for anything like L<Any::Moose> for Moo
c100c04c 283code - Moo and Moose code should simply interoperate without problem. To
284handle L<Mouse> code, you'll likely need an empty Moo role or class consuming
285or extending the L<Mouse> stuff since it doesn't register true L<Moose>
71bd6a81 286metaclasses like L<Moo> does.
287
288If you want types to be upgraded to the L<Moose> types, use
289L<MooX::Types::MooseLike> and install the L<MooseX::Types> library to
290match the L<MooX::Types::MooseLike> library you're using - L<Moo> will
291load the L<MooseX::Types> library and use that type for the newly created
292metaclass.
660f3db2 293
1fce5bc9 294If you need to disable the metaclass creation, add:
295
296 no Moo::sification;
297
298to your code before Moose is loaded, but bear in mind that this switch is
a297a9ab 299currently global and turns the mechanism off entirely so don't put this
300in library code.
1fce5bc9 301
8146585e 302=head1 IMPORTED METHODS
303
304=head2 new
305
306 Foo::Bar->new( attr1 => 3 );
307
308or
309
310 Foo::Bar->new({ attr1 => 3 });
311
2e575bcd 312=head2 BUILDARGS
313
f2eac33e 314 sub BUILDARGS {
a17be455 315 my ( $class, @args ) = @_;
316
317 unshift @args, "attr1" if @args % 2 == 1;
318
f2eac33e 319 return { @args };
a17be455 320 };
321
322 Foo::Bar->new( 3 );
323
324The default implementation of this method accepts a hash or hash reference of
325named parameters. If it receives a single argument that isn't a hash reference
326it throws an error.
327
328You can override this method in your class to handle other types of options
329passed to the constructor.
330
331This method should always return a hash reference of named options.
2e575bcd 332
2d00f3d6 333=head2 BUILD
8146585e 334
2d00f3d6 335Define a C<BUILD> method on your class and the constructor will automatically
336call the C<BUILD> method from parent down to child after the object has
337been instantiated. Typically this is used for object validation or possibly
338logging.
8146585e 339
2d00f3d6 340=head2 DEMOLISH
c2cc003f 341
debb3fcd 342If you have a C<DEMOLISH> method anywhere in your inheritance hierarchy,
343a C<DESTROY> method is created on first object construction which will call
c2cc003f 344C<< $instance->DEMOLISH($in_global_destruction) >> for each C<DEMOLISH>
debb3fcd 345method from child upwards to parents.
346
347Note that the C<DESTROY> method is created on first construction of an object
348of your class in order to not add overhead to classes without C<DEMOLISH>
349methods; this may prove slightly surprising if you try and define your own.
c2cc003f 350
8146585e 351=head2 does
352
353 if ($foo->does('Some::Role1')) {
354 ...
355 }
356
357Returns true if the object composes in the passed role.
358
359=head1 IMPORTED SUBROUTINES
360
361=head2 extends
362
363 extends 'Parent::Class';
364
2e575bcd 365Declares base class. Multiple superclasses can be passed for multiple
366inheritance (but please use roles instead).
367
368Calling extends more than once will REPLACE your superclasses, not add to
369them like 'use base' would.
8146585e 370
371=head2 with
372
373 with 'Some::Role1';
8146585e 374
f9755246 375or
376
377 with 'Some::Role1', 'Some::Role2';
378
379Composes one or more L<Moo::Role> (or L<Role::Tiny>) roles into the current
380class. An error will be raised if these roles have conflicting methods.
8146585e 381
382=head2 has
383
384 has attr => (
385 is => 'ro',
386 );
387
388Declares an attribute for the class.
389
390The options for C<has> are as follows:
391
392=over 2
393
394=item * is
395
6577509a 396B<required>, may be C<ro>, C<lazy>, C<rwp> or C<rw>.
71db76ce 397
398C<ro> generates an accessor that dies if you attempt to write to it - i.e.
399a getter only - by defaulting C<reader> to the name of the attribute.
400
71db76ce 401C<lazy> generates a reader like C<ro>, but also sets C<lazy> to 1 and
402C<builder> to C<_build_${attribute_name}> to allow on-demand generated
403attributes. This feature was my attempt to fix my incompetence when
404originally designing C<lazy_build>, and is also implemented by
405L<MooseX::AttributeShortcuts>.
406
407C<rwp> generates a reader like C<ro>, but also sets C<writer> to
408C<_set_${attribute_name}> for attributes that are designed to be written
409from inside of the class, but read-only from outside.
410This feature comes from L<MooseX::AttributeShortcuts>.
8146585e 411
6577509a 412C<rw> generates a normal getter/setter by defaulting C<accessor> to the
413name of the attribute.
414
8146585e 415=item * isa
416
417Takes a coderef which is meant to validate the attribute. Unlike L<Moose> Moo
418does not include a basic type system, so instead of doing C<< isa => 'Num' >>,
419one should do
420
421 isa => quote_sub q{
422 die "$_[0] is not a number!" unless looks_like_number $_[0]
423 },
424
425L<Sub::Quote aware|/SUB QUOTE AWARE>
426
c4074652 427Since L<Moo> does B<not> run the C<isa> check before C<coerce> if a coercion
428subroutine has been supplied, C<isa> checks are not structural to your code
429and can, if desired, be omitted on non-debug builds (although if this results
430in an uncaught bug causing your program to break, the L<Moo> authors guarantee
431nothing except that you get to keep both halves).
432
71db76ce 433If you want L<MooseX::Types> style named types, look at
434L<MooX::Types::MooseLike>.
435
436To cause your C<isa> entries to be automatically mapped to named
437L<Moose::Meta::TypeConstraint> objects (rather than the default behaviour
438of creating an anonymous type), set:
439
440 $Moo::HandleMoose::TYPE_MAP{$isa_coderef} = sub {
441 require MooseX::Types::Something;
442 return MooseX::Types::Something::TypeName();
443 };
444
445Note that this example is purely illustrative; anything that returns a
446L<Moose::Meta::TypeConstraint> object or something similar enough to it to
447make L<Moose> happy is fine.
448
8146585e 449=item * coerce
450
451Takes a coderef which is meant to coerce the attribute. The basic idea is to
452do something like the following:
453
454 coerce => quote_sub q{
455 $_[0] + 1 unless $_[0] % 2
456 },
457
c4074652 458Note that L<Moo> will always fire your coercion - this is to permit
459isa entries to be used purely for bug trapping, whereas coercions are
460always structural to your code. We do, however, apply any supplied C<isa>
461check after the coercion has run to ensure that it returned a valid value.
8146585e 462
23a3e34e 463L<Sub::Quote aware|/SUB QUOTE AWARE>
2e575bcd 464
e1efec09 465=item * handles
466
467Takes a string
468
69673ca7 469 handles => 'RobotRole'
470
471Where C<RobotRole> is a role (L<Moo::Role>) that defines an interface which
472becomes the list of methods to handle.
e1efec09 473
474Takes a list of methods
475
476 handles => [ qw( one two ) ]
477
478Takes a hashref
479
480 handles => {
481 un => 'one',
482 }
483
8146585e 484=item * trigger
485
6fe5100d 486Takes a coderef which will get called any time the attribute is set. This
487includes the constructor. Coderef will be invoked against the object with the
488new value as an argument.
8146585e 489
71db76ce 490If you set this to just C<1>, it generates a trigger which calls the
491C<_trigger_${attr_name}> method on C<$self>. This feature comes from
492L<MooseX::AttributeShortcuts>.
493
2e575bcd 494Note that Moose also passes the old value, if any; this feature is not yet
495supported.
496
8146585e 497L<Sub::Quote aware|/SUB QUOTE AWARE>
498
499=item * default
500
2e575bcd 501Takes a coderef which will get called with $self as its only argument
502to populate an attribute if no value is supplied to the constructor - or
503if the attribute is lazy, when the attribute is first retrieved if no
504value has yet been provided.
505
506Note that if your default is fired during new() there is no guarantee that
507other attributes have been populated yet so you should not rely on their
508existence.
8146585e 509
510L<Sub::Quote aware|/SUB QUOTE AWARE>
511
512=item * predicate
513
2e575bcd 514Takes a method name which will return true if an attribute has a value.
8146585e 515
71db76ce 516If you set this to just C<1>, the predicate is automatically named
517C<has_${attr_name}> if your attribute's name does not start with an
518underscore, or <_has_${attr_name_without_the_underscore}> if it does.
519This feature comes from L<MooseX::AttributeShortcuts>.
8146585e 520
521=item * builder
522
2e575bcd 523Takes a method name which will be called to create the attribute - functions
524exactly like default except that instead of calling
525
526 $default->($self);
527
528Moo will call
529
530 $self->$builder;
8146585e 531
71db76ce 532If you set this to just C<1>, the predicate is automatically named
533C<_build_${attr_name}>. This feature comes from L<MooseX::AttributeShortcuts>.
534
8146585e 535=item * clearer
536
537Takes a method name which will clear the attribute.
538
71db76ce 539If you set this to just C<1>, the clearer is automatically named
540C<clear_${attr_name}> if your attribute's name does not start with an
541underscore, or <_clear_${attr_name_without_the_underscore}> if it does.
542This feature comes from L<MooseX::AttributeShortcuts>.
543
8146585e 544=item * lazy
545
546B<Boolean>. Set this if you want values for the attribute to be grabbed
547lazily. This is usually a good idea if you have a L</builder> which requires
548another attribute to be set.
549
550=item * required
551
552B<Boolean>. Set this if the attribute must be passed on instantiation.
553
1eba910c 554=item * reader
555
556The value of this attribute will be the name of the method to get the value of
557the attribute. If you like Java style methods, you might set this to
558C<get_foo>
559
560=item * writer
561
562The value of this attribute will be the name of the method to set the value of
563the attribute. If you like Java style methods, you might set this to
564C<set_foo>
565
8146585e 566=item * weak_ref
567
568B<Boolean>. Set this if you want the reference that the attribute contains to
569be weakened; use this when circular references are possible, which will cause
570leaks.
571
572=item * init_arg
573
574Takes the name of the key to look for at instantiation time of the object. A
575common use of this is to make an underscored attribute have a non-underscored
576initialization name. C<undef> means that passing the value in on instantiation
71db76ce 577is ignored.
8146585e 578
579=back
580
581=head2 before
582
583 before foo => sub { ... };
584
585See L<< Class::Method::Modifiers/before method(s) => sub { ... } >> for full
586documentation.
587
588=head2 around
589
590 around foo => sub { ... };
591
592See L<< Class::Method::Modifiers/around method(s) => sub { ... } >> for full
593documentation.
594
595=head2 after
596
597 after foo => sub { ... };
598
599See L<< Class::Method::Modifiers/after method(s) => sub { ... } >> for full
600documentation.
601
8146585e 602=head1 SUB QUOTE AWARE
603
604L<Sub::Quote/quote_sub> allows us to create coderefs that are "inlineable,"
605giving us a handy, XS-free speed boost. Any option that is L<Sub::Quote>
606aware can take advantage of this.
607
2e575bcd 608=head1 INCOMPATIBILITIES WITH MOOSE
8146585e 609
5902c1fc 610There is no built in type system. C<isa> is verified with a coderef, if you
8146585e 611need complex types, just make a library of coderefs, or better yet, functions
5902c1fc 612that return quoted subs. L<MooX::Types::MooseLike> provides a similar API
613to L<MooseX::Types::Moose> so that you can write
614
615 has days_to_live => (is => 'ro', isa => Int);
616
617and have it work with both; it is hoped that providing only subrefs as an
618API will encourage the use of other type systems as well, since it's
619probably the weakest part of Moose design-wise.
8146585e 620
2e575bcd 621C<initializer> is not supported in core since the author considers it to be a
f88623a1 622bad idea but may be supported by an extension in future. Meanwhile C<trigger> or
623C<coerce> are more likely to be able to fulfill your needs.
8146585e 624
625There is no meta object. If you need this level of complexity you wanted
2e575bcd 626L<Moose> - Moo succeeds at being small because it explicitly does not
f9755246 627provide a metaprotocol. However, if you load L<Moose>, then
628
629 Class::MOP::class_of($moo_class_or_role)
630
631will return an appropriate metaclass pre-populated by L<Moo>.
8146585e 632
13e41b70 633No support for C<super>, C<override>, C<inner>, or C<augment> - the author
634considers augment to be a bad idea, and override can be translated:
635
636 override foo => sub {
637 ...
638 super();
639 ...
640 };
641
642 around foo => sub {
643 my ($orig, $self) = (shift, shift);
644 ...
645 $self->$orig(@_);
646 ...
647 };
8146585e 648
f2eac33e 649The C<dump> method is not provided by default. The author suggests loading
c96a6326 650L<Devel::Dwarn> into C<main::> (via C<perl -MDevel::Dwarn ...> for example) and
651using C<$obj-E<gt>$::Dwarn()> instead.
652
8146585e 653L</default> only supports coderefs, because doing otherwise is usually a
654mistake anyway.
655
f9755246 656C<lazy_build> is not supported; you are instead encouraged to use the
657C<is => 'lazy'> option supported by L<Moo> and L<MooseX::AttributeShortcuts>.
8146585e 658
2e575bcd 659C<auto_deref> is not supported since the author considers it a bad idea.
8146585e 660
f9755246 661C<documentation> will show up in a L<Moose> metaclass created from your class
c4074652 662but is otherwise ignored. Then again, L<Moose> ignores it as well, so this
f9755246 663is arguably not an incompatibility.
40f3e3aa 664
c4074652 665Since C<coerce> does not require C<isa> to be defined but L<Moose> does
666require it, the metaclass inflation for coerce-alone is a trifle insane
667and if you attempt to subtype the result will almost certainly break.
668
69673ca7 669Handling of warnings: when you C<use Moo> we enable FATAL warnings. The nearest
670similar invocation for L<Moose> would be:
671
672 use Moose;
673 use warnings FATAL => "all";
674
675Additionally, L<Moo> supports a set of attribute option shortcuts intended to
676reduce common boilerplate. The set of shortcuts is the same as in the L<Moose>
239d4711 677module L<MooseX::AttributeShortcuts> as of its version 0.009+. So if you:
69673ca7 678
679 package MyClass;
680 use Moo;
681
682The nearest L<Moose> invocation would be:
683
684 package MyClass;
685
686 use Moose;
687 use warnings FATAL => "all";
688 use MooseX::AttributeShortcuts;
689
5902c1fc 690or, if you're inheriting from a non-Moose class,
691
692 package MyClass;
693
694 use Moose;
695 use MooseX::NonMoose;
696 use warnings FATAL => "all";
697 use MooseX::AttributeShortcuts;
698
699Finally, Moose requires you to call
700
701 __PACKAGE__->meta->make_immutable;
702
703at the end of your class to get an inlined (i.e. not horribly slow)
704constructor. Moo does it automatically the first time ->new is called
705on your class.
706
660f3db2 707=head1 SUPPORT
708
9836a6ee 709Users' IRC: #moose on irc.perl.org
710
711Development and contribution IRC: #web-simple on irc.perl.org
660f3db2 712
40f3e3aa 713=head1 AUTHOR
714
715mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
716
717=head1 CONTRIBUTORS
718
5da684a2 719dg - David Leadbeater (cpan:DGL) <dgl@dgl.cx>
720
721frew - Arthur Axel "fREW" Schmidt (cpan:FREW) <frioux@gmail.com>
722
723hobbs - Andrew Rodland (cpan:ARODLAND) <arodland@cpan.org>
724
725jnap - John Napiorkowski (cpan:JJNAPIORK) <jjn1056@yahoo.com>
726
727ribasushi - Peter Rabbitson (cpan:RIBASUSHI) <ribasushi@cpan.org>
40f3e3aa 728
11f7a042 729chip - Chip Salzenberg (cpan:CHIPS) <chip@pobox.com>
730
a17be455 731ajgb - Alex J. G. Burzyński (cpan:AJGB) <ajgb@cpan.org>
732
7b8177f8 733doy - Jesse Luehrs (cpan:DOY) <doy at tozt dot net>
734
1fb2de92 735perigrin - Chris Prather (cpan:PERIGRIN) <chris@prather.org>
736
3202e039 737Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@googlemail.com>
738
e355471c 739ilmari - Dagfinn Ilmari Mannsåker (cpan:ILMARI) <ilmari@ilmari.org>
740
40f3e3aa 741=head1 COPYRIGHT
742
a958e36d 743Copyright (c) 2010-2011 the Moo L</AUTHOR> and L</CONTRIBUTORS>
40f3e3aa 744as listed above.
745
746=head1 LICENSE
747
748This library is free software and may be distributed under the same terms
749as perl itself.
750
751=cut