MooX::HandlesVia and roles

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;
}

Comments are closed.