Quoth tho...@sandlass.de ("TSa (Thomas =?utf-8?q?Sandla=C3=9F?=)"): > > Here is a direct syntax for the freeze feature of the paper: > > class C does T1 does T2 > { > freeze T1::x for foo; > freeze T2::x for bar; > method x {...} # for all other methods > } > > The implementation is strait forward: on entry to foo and bar > the dispatch table of the invocant is temporarily patched to > contain the right x. After the call the original is restored.
Isn't this just sugar for something like class C does T1 does T2 { method foo { my $tmp = self but role { method x { return self.T1::x } }; return $tmp.foo; } method x { ... } } (Excuse me if I have any syntactic details wrong.) The most important detail here is that the *class* gets to pick which imported methods need to be wrapped. Most of the time you want a method x in the class to be called from a method foo in the role: that's the point. What this doesn't fix is that some other code (outside the class) will be expecting C::x to have T1::x semantics, and some will be expecting it to have T2::x semantics. If these are contradictory, there is no way to write an x which works. That's where the 'hats' idea comes in, so you could write something like class C does T1 does T2 { method T1::x { ... } method T2::x { ... } } and have callers that thought they were getting a T1 call the appropriate override. However, there's still a problem with callers that know they have a C: which method do they get? AFAICS the only real solution to this is something like COM, where you say 'I would like to talk to this object as though it were a T1 now'. Might it be possible to use the type system to make this less painful than it usually is? Ben