I’ve been using Moo for Perl object-oriented programming for a while now. It’s really quite nice, it certainly does everything I need and it’s much lighter than Moose.
Whilst working on the LCFG v4 client project I recently came across a problem with the MooX::HandlesVia module when used in conjunction with roles. I thought it worth blogging about if only to save some other pour soul from a lot of head scratching (probably me in 6 months time).
If a class is composed of more than one role and each role uses the MooX::HandlesVia module, for example:
{ package SJQ::Role::Foo; use Moo::Role; use MooX::HandlesVia; } { package SJQ::Role::Bar; use Moo::Role; use MooX::HandlesVia; } { package SJQ::Baz; use Moo; with 'SJQ::Role::Foo','SJQ::Role::Bar'; use namespace::clean; } my $test = SJQ::Baz->new();
It fails and the following error message is generated:
Due to a method name conflict between roles 'SJQ::Role::Bar and SJQ::Role::Foo', the method 'has' must be implemented by 'SJQ::Baz' at /usr/share/perl5/vendor_perl/Role/Tiny.pm line 215.
It appears that MooX::HandlesVia provides its own replacement has
method and this causes a problem when namespace::clean is also used.
The solution is to apply the roles separately, it’s perfectly allowable to call the with
method several times. For example:
{ package SJQ::Baz; use Moo; with 'SJQ::Role::Foo'; with 'SJQ::Role::Bar'; use namespace::clean; }