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)
============================================================*/