1package Role::Tiny;
2use strict;
3use warnings;
4
5our $VERSION = '2.002004';
6$VERSION =~ tr/_//d;
7
8our %INFO;
9our %APPLIED_TO;
10our %COMPOSED;
11our %COMPOSITE_INFO;
12our @ON_ROLE_CREATE;
13
14# Module state workaround totally stolen from Zefram's Module::Runtime.
15
16BEGIN {
17  *_WORK_AROUND_BROKEN_MODULE_STATE = "$]" < 5.009 ? sub(){1} : sub(){0};
18  *_WORK_AROUND_HINT_LEAKAGE
19    = "$]" < 5.011 && !("$]" >= 5.009004 && "$]" < 5.010001)
20      ? sub(){1} : sub(){0};
21  *_CONSTANTS_DEFLATE = "$]" >= 5.012 && "$]" < 5.020 ? sub(){1} : sub(){0};
22}
23
24sub _getglob { no strict 'refs'; \*{$_[0]} }
25sub _getstash { no strict 'refs'; \%{"$_[0]::"} }
26
27sub croak {
28  require Carp;
29  no warnings 'redefine';
30  *croak = \&Carp::croak;
31  goto &Carp::croak;
32}
33
34sub Role::Tiny::__GUARD__::DESTROY {
35  delete $INC{$_[0]->[0]} if @{$_[0]};
36}
37
38sub _load_module {
39  my ($module) = @_;
40  (my $file = "$module.pm") =~ s{::}{/}g;
41  return 1
42    if $INC{$file};
43
44  # can't just ->can('can') because a sub-package Foo::Bar::Baz
45  # creates a 'Baz::' key in Foo::Bar's symbol table
46  return 1
47    if grep !/::\z/, keys %{_getstash($module)};
48  my $guard = _WORK_AROUND_BROKEN_MODULE_STATE
49    && bless([ $file ], 'Role::Tiny::__GUARD__');
50  local %^H if _WORK_AROUND_HINT_LEAKAGE;
51  require $file;
52  pop @$guard if _WORK_AROUND_BROKEN_MODULE_STATE;
53  return 1;
54}
55
56sub _require_module {
57  _load_module($_[1]);
58}
59
60sub _all_subs {
61  my ($me, $package) = @_;
62  my $stash = _getstash($package);
63  return {
64    map {;
65      no strict 'refs';
66      # this is an ugly hack to populate the scalar slot of any globs, to
67      # prevent perl from converting constants back into scalar refs in the
68      # stash when they are used (perl 5.12 - 5.18). scalar slots on their own
69      # aren't detectable through pure perl, so this seems like an acceptable
70      # compromise.
71      ${"${package}::${_}"} = ${"${package}::${_}"}
72        if _CONSTANTS_DEFLATE;
73      $_ => \&{"${package}::${_}"}
74    }
75    grep exists &{"${package}::${_}"},
76    grep !/::\z/,
77    keys %$stash
78  };
79}
80
81sub import {
82  my $target = caller;
83  my $me = shift;
84  strict->import;
85  warnings->import;
86  my $non_methods = $me->_non_methods($target);
87  $me->_install_subs($target, @_);
88  $me->make_role($target);
89  $me->_mark_new_non_methods($target, $non_methods)
90    if $non_methods && %$non_methods;
91  return;
92}
93
94sub _mark_new_non_methods {
95  my ($me, $target, $old_non_methods) = @_;
96
97  my $non_methods = $INFO{$target}{non_methods};
98
99  my $subs = $me->_all_subs($target);
100  for my $sub (keys %$subs) {
101    if ( exists $old_non_methods->{$sub} && $non_methods->{$sub} != $subs->{$sub} ) {
102      $non_methods->{$sub} = $subs->{$sub};
103    }
104  }
105
106  return;
107}
108
109sub make_role {
110  my ($me, $target) = @_;
111
112  return if $me->is_role($target);
113  $INFO{$target}{is_role} = 1;
114
115  my $non_methods = $me->_all_subs($target);
116  delete @{$non_methods}{grep /\A\(/, keys %$non_methods};
117  $INFO{$target}{non_methods} = $non_methods;
118
119  # a role does itself
120  $APPLIED_TO{$target} = { $target => undef };
121  foreach my $hook (@ON_ROLE_CREATE) {
122    $hook->($target);
123  }
124}
125
126sub _install_subs {
127  my ($me, $target) = @_;
128  return if $me->is_role($target);
129  my %install = $me->_gen_subs($target);
130  *{_getglob("${target}::${_}")} = $install{$_}
131    for sort keys %install;
132  return;
133}
134
135sub _gen_subs {
136  my ($me, $target) = @_;
137  (
138    (map {;
139      my $type = $_;
140      $type => sub {
141        my $code = pop;
142        my @names = ref $_[0] eq 'ARRAY' ? @{ $_[0] } : @_;
143        push @{$INFO{$target}{modifiers}||=[]}, [ $type, @names, $code ];
144        return;
145      };
146    } qw(before after around)),
147    requires => sub {
148      push @{$INFO{$target}{requires}||=[]}, @_;
149      return;
150    },
151    with => sub {
152      $me->apply_roles_to_package($target, @_);
153      return;
154    },
155  );
156}
157
158sub role_application_steps {
159  qw(
160    _install_methods
161    _check_requires
162    _install_modifiers
163    _copy_applied_list
164  );
165}
166
167sub _copy_applied_list {
168  my ($me, $to, $role) = @_;
169  # copy our role list into the target's
170  @{$APPLIED_TO{$to}||={}}{keys %{$APPLIED_TO{$role}}} = ();
171}
172
173sub apply_roles_to_object {
174  my ($me, $object, @roles) = @_;
175  my $class = ref($object);
176  # on perl < 5.8.9, magic isn't copied to all ref copies. bless the parameter
177  # directly, so at least the variable passed to us will get any magic applied
178  bless($_[1], $me->create_class_with_roles($class, @roles));
179}
180
181my $role_suffix = 'A000';
182sub _composite_name {
183  my ($me, $superclass, @roles) = @_;
184
185  my $new_name = $superclass . '__WITH__' . join '__AND__', @roles;
186
187  if (length($new_name) > 252) {
188    $new_name = $COMPOSED{abbrev}{$new_name} ||= do {
189      my $abbrev = substr $new_name, 0, 250 - length $role_suffix;
190      $abbrev =~ s/(?<!:):$//;
191      $abbrev.'__'.$role_suffix++;
192    };
193  }
194  return $new_name;
195}
196
197sub create_class_with_roles {
198  my ($me, $superclass, @roles) = @_;
199
200  $me->_require_module($superclass);
201  $me->_check_roles(@roles);
202
203  my $new_name = $me->_composite_name($superclass, @roles);
204
205  return $new_name
206    if $COMPOSED{class}{$new_name};
207
208  return $me->_build_class_with_roles($new_name, $superclass, @roles);
209}
210
211sub _build_class_with_roles {
212  my ($me, $new_name, $superclass, @roles) = @_;
213
214  $COMPOSED{base}{$new_name} = $superclass;
215  @{*{_getglob("${new_name}::ISA")}} = ( $superclass );
216  $me->apply_roles_to_package($new_name, @roles);
217  $COMPOSED{class}{$new_name} = 1;
218  return $new_name;
219}
220
221sub _check_roles {
222  my ($me, @roles) = @_;
223  croak "No roles supplied!" unless @roles;
224
225  my %seen;
226  if (my @dupes = grep 1 == $seen{$_}++, @roles) {
227    croak "Duplicated roles: ".join(', ', @dupes);
228  }
229
230  foreach my $role (@roles) {
231    $me->_require_module($role);
232    croak "${role} is not a ${me}" unless $me->is_role($role);
233  }
234}
235
236our %BACKCOMPAT_HACK;
237$BACKCOMPAT_HACK{+__PACKAGE__} = 0;
238sub _want_backcompat_hack {
239  my $me = shift;
240  return $BACKCOMPAT_HACK{$me}
241    if exists $BACKCOMPAT_HACK{$me};
242  no warnings 'uninitialized';
243  $BACKCOMPAT_HACK{$me} =
244    $me->can('apply_single_role_to_package') != \&apply_single_role_to_package
245    && $me->can('role_application_steps') == \&role_application_steps
246}
247
248our $IN_APPLY_ROLES;
249sub apply_single_role_to_package {
250  return
251    if $IN_APPLY_ROLES;
252  local $IN_APPLY_ROLES = 1;
253
254  my ($me, $to, $role) = @_;
255  $me->apply_roles_to_package($to, $role);
256}
257
258sub apply_role_to_package {
259  my ($me, $to, $role) = @_;
260  $me->apply_roles_to_package($to, $role);
261}
262
263sub apply_roles_to_package {
264  my ($me, $to, @roles) = @_;
265  croak "Can't apply roles to object with apply_roles_to_package"
266    if ref $to;
267
268  $me->_check_roles(@roles);
269
270  my @have_conflicts;
271  my %role_methods;
272
273  if (@roles > 1) {
274    my %conflicts = %{$me->_composite_info_for(@roles)->{conflicts}};
275    @have_conflicts = grep $to->can($_), keys %conflicts;
276    delete @conflicts{@have_conflicts};
277
278    if (keys %conflicts) {
279      my $class = $COMPOSED{base}{$to} || $to;
280      my $fail =
281        join "\n",
282          map {
283            "Due to a method name conflict between roles "
284            .join(' and ', map "'$_'", sort values %{$conflicts{$_}})
285            .", the method '$_' must be implemented by '$class'"
286          } sort keys %conflicts;
287      croak $fail;
288    }
289
290    %role_methods = map +($_ => $me->_concrete_methods_of($_)), @roles;
291  }
292
293  if (!$IN_APPLY_ROLES and _want_backcompat_hack($me)) {
294    local $IN_APPLY_ROLES = 1;
295    foreach my $role (@roles) {
296      $me->apply_single_role_to_package($to, $role);
297    }
298  }
299
300  my $role_methods;
301  foreach my $step ($me->role_application_steps) {
302    foreach my $role (@roles) {
303      # conflicting methods are supposed to be treated as required by the
304      # composed role. we don't have an actual composed role, but because
305      # we know the target class already provides them, we can instead
306      # pretend that the roles don't do for the duration of application.
307      $role_methods = $role_methods{$role} and (
308        (local @{$role_methods}{@have_conflicts}),
309        (delete @{$role_methods}{@have_conflicts}),
310      );
311
312      $me->$step($to, $role);
313    }
314  }
315  $APPLIED_TO{$to}{join('|',@roles)} = 1;
316}
317
318sub _composite_info_for {
319  my ($me, @roles) = @_;
320  $COMPOSITE_INFO{join('|', sort @roles)} ||= do {
321    my %methods;
322    foreach my $role (@roles) {
323      my $this_methods = $me->_concrete_methods_of($role);
324      $methods{$_}{$this_methods->{$_}} = $role for keys %$this_methods;
325    }
326    delete $methods{$_} for grep keys(%{$methods{$_}}) == 1, keys %methods;
327    +{ conflicts => \%methods }
328  };
329}
330
331sub _check_requires {
332  my ($me, $to, $name, $requires) = @_;
333  $requires ||= $INFO{$name}{requires} || [];
334  if (my @requires_fail = grep !$to->can($_), @$requires) {
335    # role -> role, add to requires, role -> class, error out
336    if (my $to_info = $INFO{$to}) {
337      push @{$to_info->{requires}||=[]}, @requires_fail;
338    } else {
339      croak "Can't apply ${name} to ${to} - missing ".join(', ', @requires_fail);
340    }
341  }
342}
343
344sub _non_methods {
345  my ($me, $role) = @_;
346  my $info = $INFO{$role} or return {};
347
348  my %non_methods = %{ $info->{non_methods} || {} };
349
350  # this is only for backwards compatibility with older Moo, which
351  # reimplements method tracking rather than calling our method
352  my %not_methods = reverse %{ $info->{not_methods} || {} };
353  return \%non_methods unless keys %not_methods;
354
355  my $subs = $me->_all_subs($role);
356  for my $sub (grep !/\A\(/, keys %$subs) {
357    my $code = $subs->{$sub};
358    if (exists $not_methods{$code}) {
359      $non_methods{$sub} = $code;
360    }
361  }
362
363  return \%non_methods;
364}
365
366sub _concrete_methods_of {
367  my ($me, $role) = @_;
368  my $info = $INFO{$role};
369
370  return $info->{methods}
371    if $info && $info->{methods};
372
373  my $non_methods = $me->_non_methods($role);
374
375  my $subs = $me->_all_subs($role);
376  for my $sub (keys %$subs) {
377    if ( exists $non_methods->{$sub} && $non_methods->{$sub} == $subs->{$sub} ) {
378      delete $subs->{$sub};
379    }
380  }
381
382  if ($info) {
383    $info->{methods} = $subs;
384  }
385  return $subs;
386}
387
388sub methods_provided_by {
389  my ($me, $role) = @_;
390  $me->_require_module($role);
391  croak "${role} is not a ${me}" unless $me->is_role($role);
392  sort (keys %{$me->_concrete_methods_of($role)}, @{$INFO{$role}->{requires}||[]});
393}
394
395sub _install_methods {
396  my ($me, $to, $role) = @_;
397
398  my $methods = $me->_concrete_methods_of($role);
399
400  my %existing_methods;
401  @existing_methods{keys %{ $me->_all_subs($to) }} = ();
402
403  # _concrete_methods_of caches its result on roles.  that cache needs to be
404  # invalidated after applying roles
405  delete $INFO{$to}{methods} if $INFO{$to};
406
407  foreach my $i (keys %$methods) {
408    next
409      if exists $existing_methods{$i};
410
411    my $glob = _getglob "${to}::${i}";
412    *$glob = $methods->{$i};
413
414    # overloads using method names have the method stored in the scalar slot
415    # and &overload::nil in the code slot.
416    next
417      unless $i =~ /^\(/
418        && ((defined &overload::nil && $methods->{$i} == \&overload::nil)
419            || (defined &overload::_nil && $methods->{$i} == \&overload::_nil));
420
421    my $overload = ${ _getglob "${role}::${i}" };
422    next
423      unless defined $overload;
424
425    *$glob = \$overload;
426  }
427
428  $me->_install_does($to);
429}
430
431sub _install_modifiers {
432  my ($me, $to, $name) = @_;
433  return unless my $modifiers = $INFO{$name}{modifiers};
434  my $info = $INFO{$to};
435  my $existing = ($info ? $info->{modifiers} : $COMPOSED{modifiers}{$to}) ||= [];
436  my @modifiers = grep {
437    my $modifier = $_;
438    !grep $_ == $modifier, @$existing;
439  } @{$modifiers||[]};
440  push @$existing, @modifiers;
441
442  if (!$info) {
443    foreach my $modifier (@modifiers) {
444      $me->_install_single_modifier($to, @$modifier);
445    }
446  }
447}
448
449my $vcheck_error;
450
451sub _install_single_modifier {
452  my ($me, @args) = @_;
453  defined($vcheck_error) or $vcheck_error = do {
454    local $@;
455    eval {
456      require Class::Method::Modifiers;
457      Class::Method::Modifiers->VERSION(1.05);
458      1;
459    } ? 0 : $@;
460  };
461  $vcheck_error and die $vcheck_error;
462  Class::Method::Modifiers::install_modifier(@args);
463}
464
465my $FALLBACK = sub { 0 };
466sub _install_does {
467  my ($me, $to) = @_;
468
469  # only add does() method to classes
470  return if $me->is_role($to);
471
472  my $does = $me->can('does_role');
473  # add does() only if they don't have one
474  *{_getglob "${to}::does"} = $does unless $to->can('does');
475
476  return
477    if $to->can('DOES') and $to->can('DOES') != (UNIVERSAL->can('DOES') || 0);
478
479  my $existing = $to->can('DOES') || $to->can('isa') || $FALLBACK;
480  my $new_sub = sub {
481    my ($proto, $role) = @_;
482    $proto->$does($role) or $proto->$existing($role);
483  };
484  no warnings 'redefine';
485  return *{_getglob "${to}::DOES"} = $new_sub;
486}
487
488# optimize for newer perls
489require mro
490  if "$]" >= 5.009_005;
491
492if (defined &mro::get_linear_isa) {
493  *_linear_isa = \&mro::get_linear_isa;
494}
495else {
496  my $e;
497  {
498    local $@;
499# this routine is simplified and not fully compatible with mro::get_linear_isa
500# but for our use the order doesn't matter, so we don't need to care
501    eval <<'END_CODE' or $e = $@;
502sub _linear_isa($;$) {
503  if (defined &mro::get_linear_isa) {
504    no warnings 'redefine', 'prototype';
505    *_linear_isa = \&mro::get_linear_isa;
506    goto &mro::get_linear_isa;
507  }
508
509  my @check = shift;
510  my @lin;
511
512  my %found;
513  while (defined(my $check = shift @check)) {
514    push @lin, $check;
515    no strict 'refs';
516    unshift @check, grep !$found{$_}++, @{"$check\::ISA"};
517  }
518
519  return \@lin;
520}
521
5221;
523END_CODE
524  }
525  die $e if defined $e;
526}
527
528sub does_role {
529  my ($proto, $role) = @_;
530  foreach my $class (@{_linear_isa(ref($proto)||$proto)}) {
531    return 1 if exists $APPLIED_TO{$class}{$role};
532  }
533  return 0;
534}
535
536sub is_role {
537  my ($me, $role) = @_;
538  return !!($INFO{$role} && (
539    $INFO{$role}{is_role}
540    # these are for backward compatibility with older Moo that overrode some
541    # methods without calling the originals, thus not getting is_role set
542    || $INFO{$role}{requires}
543    || $INFO{$role}{not_methods}
544    || $INFO{$role}{non_methods}
545  ));
546}
547
5481;
549__END__
550
551=encoding utf-8
552
553=head1 NAME
554
555Role::Tiny - Roles: a nouvelle cuisine portion size slice of Moose
556
557=head1 SYNOPSIS
558
559 package Some::Role;
560
561 use Role::Tiny;
562
563 sub foo { ... }
564
565 sub bar { ... }
566
567 around baz => sub { ... };
568
569 1;
570
571elsewhere
572
573 package Some::Class;
574
575 use Role::Tiny::With;
576
577 # bar gets imported, but not foo
578 with 'Some::Role';
579
580 sub foo { ... }
581
582 # baz is wrapped in the around modifier by Class::Method::Modifiers
583 sub baz { ... }
584
585 1;
586
587If you wanted attributes as well, look at L<Moo::Role>.
588
589=head1 DESCRIPTION
590
591C<Role::Tiny> is a minimalist role composition tool.
592
593=head1 ROLE COMPOSITION
594
595Role composition can be thought of as much more clever and meaningful multiple
596inheritance.  The basics of this implementation of roles is:
597
598=over 2
599
600=item *
601
602If a method is already defined on a class, that method will not be composed in
603from the role. A method inherited by a class gets overridden by the role's
604method of the same name, though.
605
606=item *
607
608If a method that the role L</requires> to be implemented is not implemented,
609role application will fail loudly.
610
611=back
612
613Unlike L<Class::C3>, where the B<last> class inherited from "wins," role
614composition is the other way around, where the class wins. If multiple roles
615are applied in a single call (single with statement), then if any of their
616provided methods clash, an exception is raised unless the class provides
617a method since this conflict indicates a potential problem.
618
619=head2 ROLE METHODS
620
621All subs created after importing Role::Tiny will be considered methods to be
622composed. For example:
623
624    package MyRole;
625    use List::Util qw(min);
626    sub mysub { }
627    use Role::Tiny;
628    use List::Util qw(max);
629    sub mymethod { }
630
631In this role, C<max> and C<mymethod> will be included when composing MyRole,
632and C<min> and C<mysub> will not. For additional control, L<namespace::clean>
633can be used to exclude undesired subs from roles.
634
635=head1 IMPORTED SUBROUTINES
636
637=head2 requires
638
639 requires qw(foo bar);
640
641Declares a list of methods that must be defined to compose role.
642
643=head2 with
644
645 with 'Some::Role1';
646
647 with 'Some::Role1', 'Some::Role2';
648
649Composes another role into the current role (or class via L<Role::Tiny::With>).
650
651If you have conflicts and want to resolve them in favour of Some::Role1 you
652can instead write:
653
654 with 'Some::Role1';
655 with 'Some::Role2';
656
657If you have conflicts and want to resolve different conflicts in favour of
658different roles, please refactor your codebase.
659
660=head2 before
661
662 before foo => sub { ... };
663
664See L<< Class::Method::Modifiers/before method(s) => sub { ... }; >> for full
665documentation.
666
667Note that since you are not required to use method modifiers,
668L<Class::Method::Modifiers> is lazily loaded and we do not declare it as
669a dependency. If your L<Role::Tiny> role uses modifiers you must depend on
670both L<Class::Method::Modifiers> and L<Role::Tiny>.
671
672=head2 around
673
674 around foo => sub { ... };
675
676See L<< Class::Method::Modifiers/around method(s) => sub { ... }; >> for full
677documentation.
678
679Note that since you are not required to use method modifiers,
680L<Class::Method::Modifiers> is lazily loaded and we do not declare it as
681a dependency. If your L<Role::Tiny> role uses modifiers you must depend on
682both L<Class::Method::Modifiers> and L<Role::Tiny>.
683
684=head2 after
685
686 after foo => sub { ... };
687
688See L<< Class::Method::Modifiers/after method(s) => sub { ... }; >> for full
689documentation.
690
691Note that since you are not required to use method modifiers,
692L<Class::Method::Modifiers> is lazily loaded and we do not declare it as
693a dependency. If your L<Role::Tiny> role uses modifiers you must depend on
694both L<Class::Method::Modifiers> and L<Role::Tiny>.
695
696=head2 Strict and Warnings
697
698In addition to importing subroutines, using C<Role::Tiny> applies L<strict> and
699L<warnings> to the caller.
700
701=head1 SUBROUTINES
702
703=head2 does_role
704
705 if (Role::Tiny::does_role($foo, 'Some::Role')) {
706   ...
707 }
708
709Returns true if class has been composed with role.
710
711This subroutine is also installed as ->does on any class a Role::Tiny is
712composed into unless that class already has an ->does method, so
713
714  if ($foo->does('Some::Role')) {
715    ...
716  }
717
718will work for classes but to test a role, one must use ::does_role directly.
719
720Additionally, Role::Tiny will override the standard Perl C<DOES> method
721for your class. However, if C<any> class in your class' inheritance
722hierarchy provides C<DOES>, then Role::Tiny will not override it.
723
724=head1 METHODS
725
726=head2 make_role
727
728 Role::Tiny->make_role('Some::Role');
729
730Makes a package into a role, but does not export any subs into it.
731
732=head2 apply_roles_to_package
733
734 Role::Tiny->apply_roles_to_package(
735   'Some::Package', 'Some::Role', 'Some::Other::Role'
736 );
737
738Composes role with package.  See also L<Role::Tiny::With>.
739
740=head2 apply_roles_to_object
741
742 Role::Tiny->apply_roles_to_object($foo, qw(Some::Role1 Some::Role2));
743
744Composes roles in order into object directly. Object is reblessed into the
745resulting class. Note that the object's methods get overridden by the role's
746ones with the same names.
747
748=head2 create_class_with_roles
749
750 Role::Tiny->create_class_with_roles('Some::Base', qw(Some::Role1 Some::Role2));
751
752Creates a new class based on base, with the roles composed into it in order.
753New class is returned.
754
755=head2 is_role
756
757 Role::Tiny->is_role('Some::Role1')
758
759Returns true if the given package is a role.
760
761=head1 CAVEATS
762
763=over 4
764
765=item * On perl 5.8.8 and earlier, applying a role to an object won't apply any
766overloads from the role to other copies of the object.
767
768=item * On perl 5.16 and earlier, applying a role to a class won't apply any
769overloads from the role to any existing instances of the class.
770
771=back
772
773=head1 SEE ALSO
774
775L<Role::Tiny> is the attribute-less subset of L<Moo::Role>; L<Moo::Role> is
776a meta-protocol-less subset of the king of role systems, L<Moose::Role>.
777
778Ovid's L<Role::Basic> provides roles with a similar scope, but without method
779modifiers, and having some extra usage restrictions.
780
781=head1 AUTHOR
782
783mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
784
785=head1 CONTRIBUTORS
786
787dg - David Leadbeater (cpan:DGL) <dgl@dgl.cx>
788
789frew - Arthur Axel "fREW" Schmidt (cpan:FREW) <frioux@gmail.com>
790
791hobbs - Andrew Rodland (cpan:ARODLAND) <arodland@cpan.org>
792
793jnap - John Napiorkowski (cpan:JJNAPIORK) <jjn1056@yahoo.com>
794
795ribasushi - Peter Rabbitson (cpan:RIBASUSHI) <ribasushi@cpan.org>
796
797chip - Chip Salzenberg (cpan:CHIPS) <chip@pobox.com>
798
799ajgb - Alex J. G. Burzyński (cpan:AJGB) <ajgb@cpan.org>
800
801doy - Jesse Luehrs (cpan:DOY) <doy at tozt dot net>
802
803perigrin - Chris Prather (cpan:PERIGRIN) <chris@prather.org>
804
805Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@googlemail.com>
806
807ilmari - Dagfinn Ilmari Mannsåker (cpan:ILMARI) <ilmari@ilmari.org>
808
809tobyink - Toby Inkster (cpan:TOBYINK) <tobyink@cpan.org>
810
811haarg - Graham Knop (cpan:HAARG) <haarg@haarg.org>
812
813=head1 COPYRIGHT
814
815Copyright (c) 2010-2012 the Role::Tiny L</AUTHOR> and L</CONTRIBUTORS>
816as listed above.
817
818=head1 LICENSE
819
820This library is free software and may be distributed under the same terms
821as perl itself.
822
823=cut
824