For some time at work we have used a simple role composition class that we call AutoRole. I felt no pressing need to see it released to CPAN since there are already many ways to do it.

Today I came across an article by ovid at http://blogs.perl.org/users/ovid/2010/01/roles-without-moose.html discussing lighter role composition for some particular types of cases where using Moose isn't possible. With that in mind, I thought I'd paste the perldoc for my module and see if there is enough interest for it. If so - on to CPAN. If not - then we'll continue using it internal only.

The module is implemented in about 80 lines of code. Here is the perldoc.

=head1 SYNOPSIS
use AutoRole
class => 'Bam',
how => 'autorequire',
methods => [qw(bar baz bim)];
use AutoRole
class => 'Bam',
how => 'compile',
methods => {
bar => 1,
baz => 1,
bim => 'bim_by_some_other_name',
};
use AutoRole
class => 'Bam',
how => $ENV{'MOD_PERL'} && 'compile', # will default to autore+quire if not mod_perl
method => 'flimflam', +
use AutoRole
class => 'Bam',
how => 'autoload', # better if you are using many many mixin m+ethods
methods => [qw(bar baz bim biz boon bong brim)]; +
use AutoRole Bam => [qw(bar baz bim)];
use AutoRole Bam => autorequire => [qw(bar baz bim)]; # same thing
use AutoRole Bam => compile => [qw(bar baz bim)];
use AutoRole Bam => methods => '*'; # load ALL methods from Bam+ - at compile time
use AutoRole Bam => '*'; # same thing +
use AutoRole 'Bam'; # same thing +
use AutoRole Bam => {'*' => qr{^bam_}}; # load All methods from Bam+ that begin with bam_
use AutoRole Bam => qr{^bam_}; # same thing +
use AutoRole Bam => qr{^(?!bam_)}; # load ALL methods not begi+nning with bam_
=head1 DESCRIPTION
AutoRole is similar to many of the CPAN variants that handle things
refered to as Traits, Roles, and Mixins. All of these are fairly
similar to each other (in Perl land) though there are subtle nuances.
If you use the type C<how> of compile - there is little difference in
using AutoRole vs. the CPAN counterparts.
If you use autorequire or autoload however, you save loading the
modules until it is necessary to do so. This allows for the creation
of "heavy" interfaces with very light frontends. AutoRole allows for
only loading extra modules if that role's interface is used.
One more win with roles/mixins/traits is that you can keep your
inheritance tree sane (rather than inheriting from a role class).
=head1 PARAMETERS
In many cases the class, how, and method keywords are not needed and
the intent can be determined based on the types of parameters.
However, you can always pass the parameter names to be specific.
=over 4
=item C<class>
This represents the class you would like to load the roles from.
=item C<how>
Can be one of compile, autorequire, or autoload. Default is
autorequire if methods are passed, default is compile if no methods
are passed or if '*' or qr{} are used for methods.
Option C<compile> will load the module and mix the specified
subs/methods in as needed at compile time.
Option C<autorequire> does not load the module at compile time,
instead it loads a stub subroutine that will require the module,
re-install the real subroutine in place of the stub, and then goto
that subroutine (to keep the call stack like it should be).
Option C<autoload> tries to do as little work as possible by only
installing an AUTOLOAD subroutine that will load the role methods when
called. This is a good option over autorequire if you have a large
number of role methods (it gives more of a runtime hit rather than a
compiletime hit).
=item C<methods> or C<method>
Takes an arrayref or hashref of names or a single method name to load+. If a hashref
is passed, the value may be a different name to alias it to, or an arr+ayref of names
to alias to. +
method => 'foo'
methods => 'foo'
methods => ['foo'],
methods => {foo => 1},
methods => {foo => 'foo'}
methods => {foo => 'bar'} # installs a method called bar+ rather than foo
methods => {foo => ['bar', 'baz']} # installs both bar and baz as+ rather than foo
You can use the special method name of C<*> to load all of the methods+ from the sub.
The downside to this is it will automatically change to compile time b+ehavior (because
it needs to lookup the list of available methods). +
method => '*'
method => {'*' => 1},
If the methods are specified with a hashref, the value of a C<*> entry
may be a regex that will be used to match method names. Note however +that this
retrieval is only one class deep - so if your role inherits from a bas+e role you
will need to load it separately. +
method => {'*' => qr{^debug}} # loads all methods beginning with d+ebug
methods => {foo => 1,
'*' => qr{^bar}, # loads foo and any other method beg+inning with bar
}
If you use C<*> and other aliases at the same time, the other aliases +win.
Since it is a common thing to do - you may also pass simply a qr{} and+ it will
work like {'*' => qr{}}.
methods => qr{^debug} # load all methods beginning with debug
methods => qr{^(?!debug)} # load all methods not beginning with de+bug
If the how option is C<compile> and no method or methods are passed, i+t will default to
'*'. However if no methods are passed on autorequire or autoload, it +will die.
=back
=head1 DIAGNOTICS
=over 4
=item C<Missing class name>
Occurs when the C<class> paramter name is used but no class name follo+ws.
=item C<Missing how type>
Occurs when the C<how> type is used but no type follows.
=item C<How type $how is invalid>
Type can only be compile or autorequire.
=item C<Method name conflict - ${pkg}::$dest already exists>
Occurs if you try and use a method name from a role that is already de+fined
as a method in your class. You can work around this by using the alia+s feature
of the C<method> parameter.
=item C<Missing list of methods to load>
Occurs if you fail to pass a list of methods during autorequire or aut+oload.
Note that if you don't pass a list under how type C<compile> it will d+efault
to '*'.
=back
=head1 AUTHOR
Paul Seamons
=cut

Ada Lovelace for the palindrome
Albert Einstein for having smelly feet
Alfred Nobel for his contribution to battlefield science
Burkhard Heim for providing the missing link between science and mysticism
Claude Shannnon for riding a unicycle at night at MIT
Donald Knuth for being such a great organist
Edward Teller for being the template for Dr. Strangelove
Edwin Hubble for pretending to be a pipe-smoking English gentleman
Erwin Schrödinger for cruelty to cats
Hedy Lamarr for weaponizing pianos
Hugh Everett for immortality, especially for cats
Isaac Newton for his occult studies
Kikunae Ikeda for discovering the secrets of soy sauce
Larry Wall for his website
Louis Camille Maillard for discovering why steaks taste good
Marie Curie for the shiny stuff
Nikola Tesla for the cool cars
Paul Dirac for speaking one word per hour when socializing
Richard Feynman for his bongo skills
Robert Oppenheimer for his in-depth knowledge of the Bhagavad Gita
Rusi P Taleyarkhan for Cold Fusion
Sigmund Freud for his Ménage ā trois
Theodor W Adorno for his contribution to the reception of jazz
Wilhelm Röntgen for the foundations of body scanners
Yulii Borisovich Khariton for the Tsar Bomba
Other (please explain why)