So today in the Moose-pen I was going to move out of the testing mode and actually do a little more coding, well some re-factoring anyway.

One of the best things about re-factoring Moose code is how easy it is to use a Role to stomp out all sort of duplicated code.

So of you may of already spotted s little anti-patter I had going on on most of my Database::Accessor classes and that was the;





has 'name' => (

required => 1,

is => 'rw',

isa => 'Str'

);





has 'alias' => (

is => 'rw',

isa => 'Str'

);



andattributes repeated over at least twice and even three times in the case of the Name. So this is a great candidate for a Role. Now the question is for me is not, whether there should be a Role but rather where should this role go.

As we know I have embedded my Database::Accessor in the Accessor.pm file and moved the package name to a separate line to hide all these little bits from PAUSE as I do not want programmer to play with them directly. The same goes for any Roles they may use as they are not meant for consumption by programmers.

Now my first role looks like this





{

package

Database::Accessor::Roles::Base;

BEGIN {

$Database::Accessor::Roles::DAD::VERSION = "0.01";

}

use Moose::Role;

has 'name' => (

required => 1,

is => 'rw',

isa => 'Str'

); has 'alias' => (

is => 'rw',

isa => 'Str'

);

1;

}





{

package

Database::Accessor::View;

use Moose;

with qw(Database::Accessor::Roles::Base);

}

{

package

Database::Accessor::Element;

use Moose;

with qw(Database::Accessor::Roles::Base);

}

{

package

Database::Accessor::Predicate;

use Moose;

with qw(Database::Accessor::Roles::Base);

...





ok( does_role($view,"Database::Accessor::Roles::Base") eq 1,"View does role Database::Accessor::Roles::Base");



ok 1 - use Database::Accessor;

ok 2 - use Database::Accessor::View;

ok 3 - Person is a View

ok 4 - View does role Database::Accessor::Roles::Base



which I tacked onto the tail end of my Accessor.pm file. Now in my Database::Accessor classes I simply cut out the same attributes then apply the roleNow I want to add in a little test for the above so I add in something like thison the the View, Element, and Predicate tests cases and I get results like thisSo everything is good and fine and I can move on. You would think so but!,

If I add in this to my View test case





ok( $view->name() eq 'person',"Has name Accessor");



I get

Can't locate object method "name" via package "Database::Accessor::View" at 10_view.t line 16.

Now wait a moment I consumed the Role and my test said it was consumed what is going on? Well in the first run of the tests my Database::Accessor::Roles::Base; was placed at the end of the Accessor.pm. It cannot go there as it is loaded after the Database::Accessor::View, so I simply moved it in Accessor.pm to before View and all my tests work fine. Not 100% sure why that is but there is a blog post there someplace?

So the moral of the story is perhaps is is a good idea to test to see if you can use an attribute that is being supplied by a role!