|Think about Loose Coupling|
Re^3: Extensions via Mooseby stvn (Monsignor)
|on Apr 29, 2011 at 13:56 UTC||Need Help??|
But, I'm still composing it before construction.
With MooseX::Traits, yes you are, however doing Role->meta->apply( $instance ) will let you do it after construction, as well the Moose::Util tools as well.
If I derive an anonymous class and then instantiate it, the amendment for C1 has to include instructions to make it change what it creates for C2 and C3.
I am not sure what you are asking here, are you looking for a trigger to be fired when C1 is reblessed into the anon-class? So that it will then do something with the C2 and C3 instances? If that is the case, no Moose does not provide that, however it would be pretty simple to just do yourself when the role is added to the C1 instance.
Now adding a role can do everything a traditional derived class can do, right? So there is no need to provide a mechanism to say "use this derived class instead of C2" in addition to the mechanism that lists all the roles that are to be applied to C2 at creation time.
When a role is applied to an instance, a new anon-class is created whose superclass is the old class (C2) and with the role added in. Then the instance is reblessed into that anon-class (see Class::MOP for all the reblessed MOP API). So, I believe I am answering your first question right when I say "Yes".
I could have the builder that instantiates C2 consult an attribute that says what roles to add to it, and the original plug-in added to that list. But, I don't like the idea of having a field that doesn't do anything except during object creation. There should be a more transient way to pass the information around.
I think I am missing a large part of your design, there are a bunch of ways to go about this, all different depending on your needs.
Maybe the builder can call something which gathers the trait's names, and the original plug-in can supply 'before' methods to grow that list. (But if I only have one instance anyway, all the extra code is worse than having a defunct slot!)
Well, the question really is, will it *always* just be one instance? As long as you don't get too carried away, it might be worth the extra effort to make it extensible.
Any more suggestions?
Like I said, there are many ways to go about this, runtime-roles (roles applied to an instance) are a powerful feature (thanks Perl 6!) and you can (ab)use them in lots of different ways. It all comes down to what is the best fit for your design.