Not a creature was stirring…

by Jerrad Pierce

Minor corrections prompted by the Mo[ou]se team, who really want you to use the larger beast. — Jerrad 2009-12-02

Not even a large and gangly Moose. As you are probably aware, Moose is a relatively nifty OO framework. However, it is somewhat hefty: 6,361 lines of code plus 14 dependencies (5,199 LOC).1

Most of its fans will tell you not to worry about that, and of course premature optimization is the root of all coal-stuffed stockings, but what if you want some shiny new toys that are a bit more svelte? Enter Mouse. Mouse is "Moose without the antlers" i.e; lacking the thorny dependencies and added heft giving you a pain in the neck.

Mouse clocks in at 5.7 kLOCs with no run-time dependencies. It runsstarts-up 4+ times faster than Moose according to its authors, at the expense of implementing only 96%a subset of its larger cousin's more superficial and sexier features.

It can be a nicer, gentler introduction to the world of Moose. Like the cervine form, the rodent provides a simple means of providing accessors which are more explicit than a generalized AUTOLOAD mechanism, while still eliminating redundant code. Plenty of other fancy OO features come along for the ride, but no "metaprotocol stuff," which some would argue is the raison d'être of Moose.

You may be willing to make such a trade-off, but what if you're not writing the code, and instead run into some other module that foists Moose upon you? That author may or may not need all of Moose, but chances are good they don't. Well, if they were kind enough to use Any::Moose instead, then the code will run with whichever is available, unless you force it by setting the currently undocumented $ENV{ANY_MOOSE} to the implementation of your choice.

What if they weren't aware of Any::Moose? You could edit their code (ick), make a local copy of Mouse and run find -typef | xargsperl -pi~ -e's/Mouse/Moose/g' (very naughty), or get a little clever. With an updated version of Package::Alias that has not yet been accepted/released,2 it is possible to dress up your Mouse as a Moose.

Unfortunately, because of the way Mouse is implemented, this magic comes at the cost of a little extra work, "Any::Moose::Forcefully". Lines 6 through 20 could easily be inlined in our code, but are placed into a separate module to make it clear that you only need the BEGIN block once in your code, as early as possible, and it will supercede any later calls to useMoose. The use of an explicit BEGIN for the class substitution clauses is key to enforce the proper order of module loading. All of these lines, except for number 7, are simply copied from Mouse itself, and amount to hardcoding a particular feature set.

Note that even if other code will compile correctly with Mouse, it's possible the code could be doing some deep introspection and you may end up with Chet rather than Comet. it is therefore recommended that you run the code's test suite against Mouse whether you force it through Package::Alias or substituting Any::Moose.

2. I've submitted a patch to Package::Alias, which is also generally useful for robustly aliasing packages and classes of any sort to another name.

My suggestion that Any::Moosebe patched to use Package::Alias magic to make it a more general solution has not been embraced, but someone is welcome to produce a proper Any::Moose::Forcefully/MooseX::Hijack::WithMouse.

As an alternative to adopting the currently unofficial implementation of Alias, and admittedly ugly Any::Moose::Forcefully or something similar, you could use the following snippet suggested by one of Moose's contributors: