tags:

views:

57

answers:

3

I have a Moose::Role that I would like to call some extra subs on the class when that role is applied to the class.

Is there an easy way to modify what happens when the role is applied, without having to dig too much into Moose::Meta::Role type coding? Ideally, I'd just like to after 'apply' => ... to add the extra stuff.

Edit:

I'm specifically using this with a DBIx::Class::Core result definition to create something like a component that also modifies the constructor. I would just write it as a component if I could get at BUILDARGS and BUILD subs for the result, but I can't seem to do. So, instead of doing load_component, I doing with 'role', but some of the effects of the component are to add belongs_to relationships to the class. Hence, I was thinking the best way to do that is during application of the role to the class.

A: 

You could use a parameterized role. There is an example on how to access the consuming class in the tutorial. That being said, I would advise you to join the Moose and DBIx-Class IRC channels or mailing lists to look for best-practices in this regard.

phaylon
+2  A: 

In a briefly-lived comment I referred you to this question, which discusses how to access the metaclass of the class the role is being applied to (e.g. so you can build onto the class conditionally). However, that's a really stinky use of MooseX::Role::Parameterized providing you that information, and it also won't work if the role is being applied to another role, not to a class.

As an alternative, you could write a sugar function which receives the meta information, and build onto the class in that way:

sub foo
{
     my ($meta, %options) = @_;

     # based on what is present in %options, add additional attributes...
     $meta->add_attribute(...);
}

See Moose::Cookbook::Extending::Recipe4 for an example of writing sugar functions.

Ether
what do you think of using traits to modify Moose::Meta::Role? that's described in the docs as the way to make simple modifications to the meta role.
Carl
A: 

What I found that works, is compact, and seems in keeping with intent in the docs is to use a trait to modify the meta role used by my particular role:

package DBIx::Class::Meta::Role::MyRole;
use Moose;
BEGIN { extends 'Moose::Meta::Role'; }
after 'apply' => sub {
## ..my mods to add extra relationships to DBIx::Class::Core result
};
no Moose;

package DBIx::Class::MyRole;
use Moose::Role -metaclass => 'DBIx::Class::Meta::Role::MyRole';
Carl