in reply to Solving the SUPER problem in Mixins with String Eval

Is there a way to avoid string evals here by rebinding a clone of a subroutine to a new package, so that SUPER resolution will start from that other class?

I'm not aware of any way of retargetting SUPER resolution. I have some similar but different needs in my work application, and I solve them by injection: I construct a class specific to the caller which is injected into the caller's @ISA, and use string eval to recompile each of the methods supplied by the mixin into that class.

So in one module I might have:

package NVC::DB::User; our @ISA = qw/ NVC::DB /; use NVC::DB::attr qw/ cache /; ...
and NVC::DB::attr will create a class NVC::DB::cache::User into which to inject the extra methods, and set:
@NVC::DB::cache::User::ISA = @NVC::DB::User::ISA; @NVC::DB::User::ISA = qw/ NVC::DB::cache::User /;

Since I'm using the string eval anyway, I take advantage of it to construct mixin methods specific to the adopting class rather than creating catch-all methods that do runtime tests to determine the correct behaviour for the class. So, for example, the cache mixin uses different code depending whether the adopting class has a single key field or multiple key fields.

Since this is all transparent to the adopter, I can turn caching on or off by adding or removing use NVC::DB::attr qw/ cache /; in the class definition.

Hugo

Replies are listed 'Best First'.
Re^2: Solving the SUPER problem in Mixins with String Eval
by tilly (Archbishop) on Oct 11, 2004 at 15:59 UTC
    I'm not aware of any way of retargetting SUPER resolution.

    When you call $obj->SUPER::foo you're actually calling the function SUPER::foo, which is caught by something like an AUTOLOAD. NEXT works the same way, except that it actually IS an AUTOLOAD that does the catching.

    Therefore if you wish to retarget SUPER::foo, you can write a SUPER::foo function and it will happen. But you'll catch everyone's SUPER::foo, so program carefully...