Since the time that I initially asked this question, we've moved some Mojo + Moose code into production. There are some caveats which I will share here. This answer was actually written by Florian Ragwitz. I'm posting on his behalf.
Mojolicious and Moose can play well together, but some care has to be taken for things to work well, and there are some caveats.
It's important that Moose's constructor is used for creating new objects. Using
MooseX::NonMoose
is an easy way to ensure that. Without calling into Moose
during object construction, many Moose features such as BUILDARGS
, BUILD
,
attribute type constraint checking, and eager builders won't work.
MooseX::NonMoose
will also delegate to the original Mojolicious::Controller
constructor, which has the behaviour of just blessing the constructor arguments
provided into a hash reference. This might result in some odd results.
For example:
package MyController;
use Moose;
use MooseX::NonMoose;
extends 'Mojolicious::Controller';
has foo => (init_arg => 'bar');
Later on...
MyController->new(bar => 42) # bless { foo => 42, bar => 42 }, 'MyController'
Note how the resulting blessed hash reference contains the keys foo
and
bar
, rather than just bar
as you'd expect from a regular Moose class. This
usually isn't a problem as long as you don't intend to use object slots with
the same name as another attribute's init_arg
.
There are also limitations on what Moose extensions can be used. Mojo requires hash-based instances, so you won't be able to use any of the non-hash-based meta instances Moose offers, like MooseX::GlobRef
and MooseX::ArrayRef
. MooseX::StrictConstructor
also won't work in
this environment, because Moose can't tell which constructor arguments were
intended to be consumed by the Mojo constructor.
Overall, combining Mojolicious and Moose should work pretty well in practice as
long as you're aware of the small caveats and are OK with not being able to use
certain Moose extensions.