Given this always refers to an enclosing class from a closure, I was surprised to find that I can't use super, not even with a named super:
class A {
virtual Void wotever() { }
}
class B : A {
override Void wotever() {
func := |->| { A.super.wotever() } // --> Err
}
}
Invalid use of 'super' within closure
build::FatalBuildErr
Some digging in the docs let me to Inheritance Types. It seems this is due to restrictions on Java's invokespecial opcode. Shame :(
I would usually try to liberate the call to super from the closure by using a variable:
But this ticket disallowed it - but I don't think that would be valid anyway (not even in Java).
Does anyone have any other suggestions?
SlimerDudeSun 1 Jun 2014
I thought I'd share my use case, which I think is quite valid. It's for caching return values of methods:
class A {
virtual Obj stuff(Str arg) { }
}
class CachingA : A {
Str:Obj? cache := [:]
override Obj stuff(Str arg) {
cache.getOrAdd(arg) { super.stuff(arg) } // --> Err
}
}
My current workaround is to split the method into 2; an override point and the actual work method:
class A {
virtual Obj stuff(Str arg) {
doStuff(arg)
}
Obj doStuff(Str arg) { ... }
}
class CachingA : A {
Str:Obj? cache := [:]
override Obj stuff(Str arg) {
cache.getOrAdd(arg) { super.doStuff(arg) }
}
}
It's not pretty from a public API point of view, but it works!
brianMon 2 Jun 2014
My current workaround is to split the method into 2; an override point and the actual work method:
That is really the only way to handle it. Generating an extra shadow method for every virtual method is also really the only way we could handle it too (which is why its not supported). Its really a shame that we don't get an invokenonvirtual opcode in the JVM. I tried several times to champion that, but don't think it will ever happen (considered a potential security hole).
SlimerDude Sat 31 May 2014
Given
this
always refers to an enclosing class from a closure, I was surprised to find that I can't usesuper
, not even with a named super:Some digging in the docs let me to Inheritance Types. It seems this is due to restrictions on Java's
invokespecial
opcode. Shame :(I would usually try to liberate the call to super from the closure by using a variable:
But this ticket disallowed it - but I don't think that would be valid anyway (not even in Java).
Does anyone have any other suggestions?
SlimerDude Sun 1 Jun 2014
I thought I'd share my use case, which I think is quite valid. It's for caching return values of methods:
My current workaround is to split the method into 2; an override point and the actual work method:
It's not pretty from a public API point of view, but it works!
brian Mon 2 Jun 2014
That is really the only way to handle it. Generating an extra shadow method for every virtual method is also really the only way we could handle it too (which is why its not supported). Its really a shame that we don't get an invokenonvirtual opcode in the JVM. I tried several times to champion that, but don't think it will ever happen (considered a potential security hole).