Acme-oop-ism Part Three: techniques
Want to write a reusable class or role to stick on CPAN? If you were planning on using Moose, how about considering Moo instead? Moo doesn't have all of Moose's features, but if your project doesn't need advanced metaprogramming, it may still have enough.
Moo is designed to interact nicely with Moose. Moose and Moo classes can extend each other. Moose classes can consume Moo roles, and vice versa. It won't much help you interact with Mouse, but two out of three ain't bad.
Role::Tiny is sometimes also an option.
Rather than creating roles intended for consumption, or base classes intended for inheriting from, each of which would potentially lock people using your module into a particular OO framework, consider creating small classes that can be delegated to.
As an example, rather than creating a
HorseDrawn role that can be applied to cart objects, create a
Horse class that cart objects can delegate conveyance to.
Moo, Mouse and Moose each have handy shortcuts (
handles) for delegated methods.
Use Moo or Class::Tiny, or even hand-written classes to keep dependencies down.
Use the surface syntax
The internals of Moo, Mouse and Moose are rather different to each other (particularly Moo). Their syntactic sugar is less so. Rather than calling
$class->meta->add_attribute(), can you get away with calling
MooseX::MungeHas provides generic logic for munging
has across OO frameworks.
Multiple code paths
As a last resort, you can add different code paths for handling Moose, Mouse and Moo. You can check to see what framework a class is using via
$class->meta->isa(...) and handle it appropriately.
Tools of the trade include run-time loading via
require or Module::Runtime, and judicious use of stringy eval.
Subclass::Of is another example.
That's all your Acme-oop for now. I'll write some more on the topic soon.