On Thu, 14 Oct 2010, Lars Balker Rasmussen wrote:

nopasted this on #moose earlier, but might as well post it for
posterity as well:

Given this tiny program:
-----
package R;
use Moose::Role;
after foo => sub { warn "R::foo" };

package A;
use Moose;
sub foo { warn "A::foo" }

package B;
use Moose;
extends 'A';
#after foo => sub { };

package C;
use Moose;
extends 'B';
after foo => sub { warn "C::foo" };

package main;

Moose::Util::apply_all_roles('B', 'R');

C->foo;
---
Why would the role application be relying on the presence or not of a
method modifier in B?  "Compile time" application with "with 'R'" in B
works as expected.  Removing the modifier in C also makes the runtime
application take, so it appears that something is cached in C?

Yes, there is some caching that I suspect is the problem. Applying the method modifier caches all the subs to be called, so when you apply the modifier to C, it caches this. When applying the modifier to B _after_ this (regardless of how it's done), Moose does not recalculate the cache for methods in C.

I suspect this is fixable.

Note that in the common case of immutable classes, we would not expect this to work (that's what immutable means ;) so I'm not sure how important this is.

Is this something that actually comes up in real code?


-dave

/*============================================================
http://VegGuide.org               http://blog.urth.org
Your guide to all that's veg      House Absolute(ly Pointless)
============================================================*/

Reply via email to