
mixin::with - declaring a mix-in class

package Dog::Retriever;
use mixin::with 'Dog';

mixin::with is used to declare mix-in classes.
Mixin classes useful for those that add new functionality to an existing class. If you find yourself doing:
package Foo::ExtraStuff;
use base 'Foo';
sub new_method { ... }
package Bar;
use base qw(Foo Foo::ExtraStuff);
it's a good indication that Foo::ExtraStuff might do better as a mixin.
Instead of mixins, please consider using traits. See Class::Trait for an implementaiton.
Basic usage is simple:
package Foo::Extra;
use mixin::with 'Foo';
sub new_thing {
my($self) = shift;
...normal method...
}
use mixin::with 'Foo' is similar to subclassing from 'Foo'.
All public methods of Foo::Extra will be mixed in. mixin::with considers all methods that don't start with an '_' as public.
There's one critical difference between a normal subclass and one intended to be mixin. It can have no private methods. Instead, use lexical methods.
my $private = sub { ... };
$self->$private(@args);
instead of
sub _private { ... }
$self->_private(@args);
Don't worry, it's the same thing.

Sometimes a mixin does not care what it mixes in with. Consider a logging or error handling mixin. For these, simply mixin with UNIVERSAL.
package My::Errors;
use mixin::with qw(UNIVERSAL);
Two reasons. One is technical, it allows SUPER to work.
The other is organizational. It rare that a mixin is intended to be mixed with any old class. It often uses methods as if it were a subclass. For this reason it is good that it declares this relationship explicitly else the mixee won't be aware of the mixin's expectations.
Good question. Traits are definately a better idea then mixins, but mixins have two advantages. They're simpler to explain, acting like a gateway drug to traits by introducing the concept of OO reuse by class composition rather than inheritance.
The other is mixins work more like a drop-in replacement for multiple inheritance. In a large, hairy hierarchy mixins can often be used to trim the inheritance bush and make sense of things with a minimum of modification to the code. Once this basic repair is done, the work of converting to traits can begin.
If these advantages don't apply, proceed directly to traits.

Michael G Schwern <schwern@pobox.com>
