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