Search code examples
moose

Moose - Why does Accessor defined in sub role does not satisfy parent role requires


I am defining an API using roles and also defining the implementation using roles. I combine multiple implementation roles into a class just before creating objects. I am running into an issue where accessor methods are not being recognized while normal methods are. Please see code below and errors received while running it. I wonder if this is an intended behavior or a bug?

Code:

use MooseX::Declare;

role api { requires qw(mymethod myattribute); }

role impl with api {
  has myattribute => (is => 'ro', default => 'zz');
  method mymethod { ...; }
}

class cl with impl {}
my $obj = cl->new;

Error:

'impl' requires the method 'myattribute' to be implemented by 'cl' at D:/lab/sbp
/perl/site/lib/Moose/Meta/Role/Application/ToClass.pm line 127

Solution

  • So the issue here (and I think it's being masked by MooseX::Declare) is a known issue where Role composition may happen before the methods are generated by the attribute. If you change your code to move the role composition to after the attribute declaration:

    role impl {
        has myattribute => (is => 'ro', default => 'zz');
        with qw(impl);
        method mymethod { ...; }
    }
    

    and the error goes away. I thought MooseX::Declare protected you against this by moving role composition to the end of the role/class declaration but it appears that isn't the case in this instance. Perhaps someone who uses MooseX::Declare more can illuminate better what's going on there.