bump version
[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
229This module is an extremely light-weight, high-performance L<Moose> replacement.
230It also avoids depending on any XS modules to allow simple deployments. The
231name C<Moo> is based on the idea that it provides almost -but not quite- two
232thirds of L<Moose>.
233
234Unlike C<Mouse> this module does not aim at full L<Moose> compatibility. See
235L</INCOMPATIBILITIES> for more details.
236
5d5bb71d 237=head1 WHY MOO EXISTS
238
239If you want a full object system with a rich Metaprotocol, L<Moose> is
240already wonderful.
241
242I've tried several times to use L<Mouse> but it's 3x the size of Moo and
243takes longer to load than most of my Moo based CGI scripts take to run.
244
245If you don't want L<Moose>, you don't want "less metaprotocol" like L<Mouse>,
246you want "as little as possible" - which means "no metaprotocol", which is
247what Moo provides.
248
249By Moo 1.0 I intend to have Moo's equivalent of L<Any::Moose> built in -
250if Moose gets loaded, any Moo class or role will act as a Moose equivalent
251if treated as such.
252
253Hence - Moo exists as its name - Minimal Object Orientation - with a pledge
254to make it smooth to upgrade to L<Moose> when you need more than minimal
255features.
256
1fce5bc9 257=head1 Moo and Moose - NEW, EXPERIMENTAL
258
259If L<Moo> detects L<Moose> being loaded, it will automatically register
260metaclasses for your L<Moo> and L<Moo::Role> packages, so you should be able
261to use them in L<Moose> code without it ever realising you aren't using
262L<Moose> everywhere.
263
264Extending a L<Moose> class or consuming a L<Moose::Role> should also work.
265
c100c04c 266So should extending a L<Mouse> class or consuming a L<Mouse::Role>.
267
660f3db2 268This means that there is no need for anything like L<Any::Moose> for Moo
c100c04c 269code - Moo and Moose code should simply interoperate without problem. To
270handle L<Mouse> code, you'll likely need an empty Moo role or class consuming
271or extending the L<Mouse> stuff since it doesn't register true L<Moose>
272metaclasses like we do.
660f3db2 273
274However, these features are new as of 0.91.0 (0.091000) so while serviceable,
275they are absolutely certain to not be 100% yet; please do report bugs.
1fce5bc9 276
277If you need to disable the metaclass creation, add:
278
279 no Moo::sification;
280
281to your code before Moose is loaded, but bear in mind that this switch is
282currently global and turns the mechanism off entirely, so don't put this
283in library code, only in a top level script as a temporary measure while
284you send a bug report.
285
8146585e 286=head1 IMPORTED METHODS
287
288=head2 new
289
290 Foo::Bar->new( attr1 => 3 );
291
292or
293
294 Foo::Bar->new({ attr1 => 3 });
295
2e575bcd 296=head2 BUILDARGS
297
f2eac33e 298 sub BUILDARGS {
a17be455 299 my ( $class, @args ) = @_;
300
301 unshift @args, "attr1" if @args % 2 == 1;
302
f2eac33e 303 return { @args };
a17be455 304 };
305
306 Foo::Bar->new( 3 );
307
308The default implementation of this method accepts a hash or hash reference of
309named parameters. If it receives a single argument that isn't a hash reference
310it throws an error.
311
312You can override this method in your class to handle other types of options
313passed to the constructor.
314
315This method should always return a hash reference of named options.
2e575bcd 316
2d00f3d6 317=head2 BUILD
8146585e 318
2d00f3d6 319Define a C<BUILD> method on your class and the constructor will automatically
320call the C<BUILD> method from parent down to child after the object has
321been instantiated. Typically this is used for object validation or possibly
322logging.
8146585e 323
2d00f3d6 324=head2 DEMOLISH
c2cc003f 325
debb3fcd 326If you have a C<DEMOLISH> method anywhere in your inheritance hierarchy,
327a C<DESTROY> method is created on first object construction which will call
c2cc003f 328C<< $instance->DEMOLISH($in_global_destruction) >> for each C<DEMOLISH>
debb3fcd 329method from child upwards to parents.
330
331Note that the C<DESTROY> method is created on first construction of an object
332of your class in order to not add overhead to classes without C<DEMOLISH>
333methods; this may prove slightly surprising if you try and define your own.
c2cc003f 334
8146585e 335=head2 does
336
337 if ($foo->does('Some::Role1')) {
338 ...
339 }
340
341Returns true if the object composes in the passed role.
342
343=head1 IMPORTED SUBROUTINES
344
345=head2 extends
346
347 extends 'Parent::Class';
348
2e575bcd 349Declares base class. Multiple superclasses can be passed for multiple
350inheritance (but please use roles instead).
351
352Calling extends more than once will REPLACE your superclasses, not add to
353them like 'use base' would.
8146585e 354
355=head2 with
356
357 with 'Some::Role1';
8146585e 358
f9755246 359or
360
361 with 'Some::Role1', 'Some::Role2';
362
363Composes one or more L<Moo::Role> (or L<Role::Tiny>) roles into the current
364class. An error will be raised if these roles have conflicting methods.
8146585e 365
366=head2 has
367
368 has attr => (
369 is => 'ro',
370 );
371
372Declares an attribute for the class.
373
374The options for C<has> are as follows:
375
376=over 2
377
378=item * is
379
6577509a 380B<required>, may be C<ro>, C<lazy>, C<rwp> or C<rw>.
71db76ce 381
382C<ro> generates an accessor that dies if you attempt to write to it - i.e.
383a getter only - by defaulting C<reader> to the name of the attribute.
384
71db76ce 385C<lazy> generates a reader like C<ro>, but also sets C<lazy> to 1 and
386C<builder> to C<_build_${attribute_name}> to allow on-demand generated
387attributes. This feature was my attempt to fix my incompetence when
388originally designing C<lazy_build>, and is also implemented by
389L<MooseX::AttributeShortcuts>.
390
391C<rwp> generates a reader like C<ro>, but also sets C<writer> to
392C<_set_${attribute_name}> for attributes that are designed to be written
393from inside of the class, but read-only from outside.
394This feature comes from L<MooseX::AttributeShortcuts>.
8146585e 395
6577509a 396C<rw> generates a normal getter/setter by defaulting C<accessor> to the
397name of the attribute.
398
8146585e 399=item * isa
400
401Takes a coderef which is meant to validate the attribute. Unlike L<Moose> Moo
402does not include a basic type system, so instead of doing C<< isa => 'Num' >>,
403one should do
404
405 isa => quote_sub q{
406 die "$_[0] is not a number!" unless looks_like_number $_[0]
407 },
408
409L<Sub::Quote aware|/SUB QUOTE AWARE>
410
c4074652 411Since L<Moo> does B<not> run the C<isa> check before C<coerce> if a coercion
412subroutine has been supplied, C<isa> checks are not structural to your code
413and can, if desired, be omitted on non-debug builds (although if this results
414in an uncaught bug causing your program to break, the L<Moo> authors guarantee
415nothing except that you get to keep both halves).
416
71db76ce 417If you want L<MooseX::Types> style named types, look at
418L<MooX::Types::MooseLike>.
419
420To cause your C<isa> entries to be automatically mapped to named
421L<Moose::Meta::TypeConstraint> objects (rather than the default behaviour
422of creating an anonymous type), set:
423
424 $Moo::HandleMoose::TYPE_MAP{$isa_coderef} = sub {
425 require MooseX::Types::Something;
426 return MooseX::Types::Something::TypeName();
427 };
428
429Note that this example is purely illustrative; anything that returns a
430L<Moose::Meta::TypeConstraint> object or something similar enough to it to
431make L<Moose> happy is fine.
432
8146585e 433=item * coerce
434
435Takes a coderef which is meant to coerce the attribute. The basic idea is to
436do something like the following:
437
438 coerce => quote_sub q{
439 $_[0] + 1 unless $_[0] % 2
440 },
441
c4074652 442Note that L<Moo> will always fire your coercion - this is to permit
443isa entries to be used purely for bug trapping, whereas coercions are
444always structural to your code. We do, however, apply any supplied C<isa>
445check after the coercion has run to ensure that it returned a valid value.
8146585e 446
23a3e34e 447L<Sub::Quote aware|/SUB QUOTE AWARE>
2e575bcd 448
e1efec09 449=item * handles
450
451Takes a string
452
69673ca7 453 handles => 'RobotRole'
454
455Where C<RobotRole> is a role (L<Moo::Role>) that defines an interface which
456becomes the list of methods to handle.
e1efec09 457
458Takes a list of methods
459
460 handles => [ qw( one two ) ]
461
462Takes a hashref
463
464 handles => {
465 un => 'one',
466 }
467
8146585e 468=item * trigger
469
6fe5100d 470Takes a coderef which will get called any time the attribute is set. This
471includes the constructor. Coderef will be invoked against the object with the
472new value as an argument.
8146585e 473
71db76ce 474If you set this to just C<1>, it generates a trigger which calls the
475C<_trigger_${attr_name}> method on C<$self>. This feature comes from
476L<MooseX::AttributeShortcuts>.
477
2e575bcd 478Note that Moose also passes the old value, if any; this feature is not yet
479supported.
480
8146585e 481L<Sub::Quote aware|/SUB QUOTE AWARE>
482
483=item * default
484
2e575bcd 485Takes a coderef which will get called with $self as its only argument
486to populate an attribute if no value is supplied to the constructor - or
487if the attribute is lazy, when the attribute is first retrieved if no
488value has yet been provided.
489
490Note that if your default is fired during new() there is no guarantee that
491other attributes have been populated yet so you should not rely on their
492existence.
8146585e 493
494L<Sub::Quote aware|/SUB QUOTE AWARE>
495
496=item * predicate
497
2e575bcd 498Takes a method name which will return true if an attribute has a value.
8146585e 499
71db76ce 500If you set this to just C<1>, the predicate is automatically named
501C<has_${attr_name}> if your attribute's name does not start with an
502underscore, or <_has_${attr_name_without_the_underscore}> if it does.
503This feature comes from L<MooseX::AttributeShortcuts>.
8146585e 504
505=item * builder
506
2e575bcd 507Takes a method name which will be called to create the attribute - functions
508exactly like default except that instead of calling
509
510 $default->($self);
511
512Moo will call
513
514 $self->$builder;
8146585e 515
71db76ce 516If you set this to just C<1>, the predicate is automatically named
517C<_build_${attr_name}>. This feature comes from L<MooseX::AttributeShortcuts>.
518
8146585e 519=item * clearer
520
521Takes a method name which will clear the attribute.
522
71db76ce 523If you set this to just C<1>, the clearer is automatically named
524C<clear_${attr_name}> if your attribute's name does not start with an
525underscore, or <_clear_${attr_name_without_the_underscore}> if it does.
526This feature comes from L<MooseX::AttributeShortcuts>.
527
8146585e 528=item * lazy
529
530B<Boolean>. Set this if you want values for the attribute to be grabbed
531lazily. This is usually a good idea if you have a L</builder> which requires
532another attribute to be set.
533
534=item * required
535
536B<Boolean>. Set this if the attribute must be passed on instantiation.
537
1eba910c 538=item * reader
539
540The value of this attribute will be the name of the method to get the value of
541the attribute. If you like Java style methods, you might set this to
542C<get_foo>
543
544=item * writer
545
546The value of this attribute will be the name of the method to set the value of
547the attribute. If you like Java style methods, you might set this to
548C<set_foo>
549
8146585e 550=item * weak_ref
551
552B<Boolean>. Set this if you want the reference that the attribute contains to
553be weakened; use this when circular references are possible, which will cause
554leaks.
555
556=item * init_arg
557
558Takes the name of the key to look for at instantiation time of the object. A
559common use of this is to make an underscored attribute have a non-underscored
560initialization name. C<undef> means that passing the value in on instantiation
71db76ce 561is ignored.
8146585e 562
563=back
564
565=head2 before
566
567 before foo => sub { ... };
568
569See L<< Class::Method::Modifiers/before method(s) => sub { ... } >> for full
570documentation.
571
572=head2 around
573
574 around foo => sub { ... };
575
576See L<< Class::Method::Modifiers/around method(s) => sub { ... } >> for full
577documentation.
578
579=head2 after
580
581 after foo => sub { ... };
582
583See L<< Class::Method::Modifiers/after method(s) => sub { ... } >> for full
584documentation.
585
8146585e 586=head1 SUB QUOTE AWARE
587
588L<Sub::Quote/quote_sub> allows us to create coderefs that are "inlineable,"
589giving us a handy, XS-free speed boost. Any option that is L<Sub::Quote>
590aware can take advantage of this.
591
2e575bcd 592=head1 INCOMPATIBILITIES WITH MOOSE
8146585e 593
5902c1fc 594There is no built in type system. C<isa> is verified with a coderef, if you
8146585e 595need complex types, just make a library of coderefs, or better yet, functions
5902c1fc 596that return quoted subs. L<MooX::Types::MooseLike> provides a similar API
597to L<MooseX::Types::Moose> so that you can write
598
599 has days_to_live => (is => 'ro', isa => Int);
600
601and have it work with both; it is hoped that providing only subrefs as an
602API will encourage the use of other type systems as well, since it's
603probably the weakest part of Moose design-wise.
8146585e 604
2e575bcd 605C<initializer> is not supported in core since the author considers it to be a
f88623a1 606bad idea but may be supported by an extension in future. Meanwhile C<trigger> or
607C<coerce> are more likely to be able to fulfill your needs.
8146585e 608
609There is no meta object. If you need this level of complexity you wanted
2e575bcd 610L<Moose> - Moo succeeds at being small because it explicitly does not
f9755246 611provide a metaprotocol. However, if you load L<Moose>, then
612
613 Class::MOP::class_of($moo_class_or_role)
614
615will return an appropriate metaclass pre-populated by L<Moo>.
8146585e 616
13e41b70 617No support for C<super>, C<override>, C<inner>, or C<augment> - the author
618considers augment to be a bad idea, and override can be translated:
619
620 override foo => sub {
621 ...
622 super();
623 ...
624 };
625
626 around foo => sub {
627 my ($orig, $self) = (shift, shift);
628 ...
629 $self->$orig(@_);
630 ...
631 };
8146585e 632
f2eac33e 633The C<dump> method is not provided by default. The author suggests loading
c96a6326 634L<Devel::Dwarn> into C<main::> (via C<perl -MDevel::Dwarn ...> for example) and
635using C<$obj-E<gt>$::Dwarn()> instead.
636
8146585e 637L</default> only supports coderefs, because doing otherwise is usually a
638mistake anyway.
639
f9755246 640C<lazy_build> is not supported; you are instead encouraged to use the
641C<is => 'lazy'> option supported by L<Moo> and L<MooseX::AttributeShortcuts>.
8146585e 642
2e575bcd 643C<auto_deref> is not supported since the author considers it a bad idea.
8146585e 644
f9755246 645C<documentation> will show up in a L<Moose> metaclass created from your class
c4074652 646but is otherwise ignored. Then again, L<Moose> ignores it as well, so this
f9755246 647is arguably not an incompatibility.
40f3e3aa 648
c4074652 649Since C<coerce> does not require C<isa> to be defined but L<Moose> does
650require it, the metaclass inflation for coerce-alone is a trifle insane
651and if you attempt to subtype the result will almost certainly break.
652
69673ca7 653Handling of warnings: when you C<use Moo> we enable FATAL warnings. The nearest
654similar invocation for L<Moose> would be:
655
656 use Moose;
657 use warnings FATAL => "all";
658
659Additionally, L<Moo> supports a set of attribute option shortcuts intended to
660reduce common boilerplate. The set of shortcuts is the same as in the L<Moose>
239d4711 661module L<MooseX::AttributeShortcuts> as of its version 0.009+. So if you:
69673ca7 662
663 package MyClass;
664 use Moo;
665
666The nearest L<Moose> invocation would be:
667
668 package MyClass;
669
670 use Moose;
671 use warnings FATAL => "all";
672 use MooseX::AttributeShortcuts;
673
5902c1fc 674or, if you're inheriting from a non-Moose class,
675
676 package MyClass;
677
678 use Moose;
679 use MooseX::NonMoose;
680 use warnings FATAL => "all";
681 use MooseX::AttributeShortcuts;
682
683Finally, Moose requires you to call
684
685 __PACKAGE__->meta->make_immutable;
686
687at the end of your class to get an inlined (i.e. not horribly slow)
688constructor. Moo does it automatically the first time ->new is called
689on your class.
690
660f3db2 691=head1 SUPPORT
692
9836a6ee 693Users' IRC: #moose on irc.perl.org
694
695Development and contribution IRC: #web-simple on irc.perl.org
660f3db2 696
40f3e3aa 697=head1 AUTHOR
698
699mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
700
701=head1 CONTRIBUTORS
702
5da684a2 703dg - David Leadbeater (cpan:DGL) <dgl@dgl.cx>
704
705frew - Arthur Axel "fREW" Schmidt (cpan:FREW) <frioux@gmail.com>
706
707hobbs - Andrew Rodland (cpan:ARODLAND) <arodland@cpan.org>
708
709jnap - John Napiorkowski (cpan:JJNAPIORK) <jjn1056@yahoo.com>
710
711ribasushi - Peter Rabbitson (cpan:RIBASUSHI) <ribasushi@cpan.org>
40f3e3aa 712
11f7a042 713chip - Chip Salzenberg (cpan:CHIPS) <chip@pobox.com>
714
a17be455 715ajgb - Alex J. G. Burzyński (cpan:AJGB) <ajgb@cpan.org>
716
7b8177f8 717doy - Jesse Luehrs (cpan:DOY) <doy at tozt dot net>
718
1fb2de92 719perigrin - Chris Prather (cpan:PERIGRIN) <chris@prather.org>
720
3202e039 721Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@googlemail.com>
722
40f3e3aa 723=head1 COPYRIGHT
724
a958e36d 725Copyright (c) 2010-2011 the Moo L</AUTHOR> and L</CONTRIBUTORS>
40f3e3aa 726as listed above.
727
728=head1 LICENSE
729
730This library is free software and may be distributed under the same terms
731as perl itself.
732
733=cut