Over Stuffed Moose
Sometimes being both newbie and a keener can be a dangerous combination. Well today I sort of fell into that trap.
Well I started doing the first refactoring of my Moose classes (not for AD&D this time this is some real world code) I was working with. So I wanted to move all the common bits into a single role then create a few 'base' classes that comsume that base roles and add some other sutff. Finally I was going to 'extend' these classes with some default values and then polish them by adding a few roles to customize the end product.
So like this
{
package Product::Base;
use Moose::Role;
. ..
}
{
package Product::Liquid;
use Moose;
with (qw(Product::Base)) ;
...
}
{
Package Product::Liquid::Air
use Moose;
extends 'Product::Liquid';
with (qw(Product::Hazmat::MDSD Product::Meta::NPC Product::Hazmat::UN1001 ));
}
And things worked fine, the birds where singing and the sun was shining.
Well then I got keen.
In my 'Product::Hazmat::MDSD' I decided to add in a 'Requires' like this
package Product::Hazmat::MDSD;
use warnings;
use strict;
use Moose::Role;
requires (qw(un_id barcode name product_meta ));# ));
To make sure any other programmer who came along after me would be able to use this Role. Well this is what I got;
Load of Product failed:Air
Error='Product::Meta::NPC|Product::Hazmat::UN1001|Product::Hazmat::MDSD' requires the methods 'un_id', 'barcode' and 'product_meta' to be implemented by 'Product::Liquid::Air' at /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/Moose/Exception.pm line 37
...
Well I could of just taken that offending line out and be done with it but I just had to find out what was wrong. Well I know 'un_id' comes from my UN1001, while barcode and product_meta from NPC. What is this? It should just be the simple case of the end role consuming from the ones that have already been used. Well I guess not
Well after lots of moving of code about I did get it to work but is was Not what I wanted. I ended up adding the 'Product::Meta::NPC' and 'Product::Hazmat::UN1001' roles to the 'Product::Liquid' package like this
{
package Product::Liquid;
use Moose;
with (qw(Product::Base Product::Meta::NPC Product::Hazmat::UN1001 )) ;
...
}
but that defeats the purpose of extending that class to another that would have the properties of Liquid Air
So where did I go wrong??
Well it seem that a 'Requires' for a role is very very strict in is interpretation of this
little tid-bit from the POD. So the 'Class' must have the method not just a consume a role that has it. The second arrangement works because by the time I get to the my 'with' in 'Product::Liquid::Air' the role methods ( 'un_id', 'barcode' and 'product_meta' ) are already part of the class.
Seems I will have to do a little more work on this??
Again I feel a little like this guy!
This is a known issue in Moose. There are TODO test cases for it all over the test suite. I believe Moo doesn't suffer from this problem.
You may be able to split your
with
in two to work around the issue: