Reputation: 3058
Ideally I'd like to be able to express the idea: "whatever would be called by foo()
in the current position in the code, give me a method reference to foo
".
Rationale: I'm working on some code that uses a lot of high-order functions and function composition. I'd like: a) it to be as terse as possible, and b) not to have to keep editing class names scattered around the code as I refactor and move functions between classes.
For example:
/* ---- foo.pkg1.Utils.groovy */
public final class Utils {
private Utils() { /* as it's all static methods */ }
static foo() { 42; }
}
/* ---- foo.pkg2.Client1.groovy */
import foo.pkg1.Utils
def f1 = Utils.&foo // <-- restates class (but works)
println f1()
/* ---- foo.pkg2.Client2.groovy */
import static foo.pkg1.Utils.*
def f2 = foo // <-- No!
// "groovy.lang.MissingPropertyException: No such property: foo ..."
println f2()
def f3 = &foo // <-- No!
// "unexpected token: & at line: 17, column: 14"
println f3()
def f4 = this.&foo // <-- Also no!
// "groovy.lang.MissingMethodException: No signature of method..."
println f4()
/* ---- foo.pkg2.Client3.groovy */
/* My best attempt ... but this only allows me to change which
class 'u' refers too, not to create a method reference to
whatever `foo()` would call at the same place in the code. */
import static Utils as u
def f5 = u.&foo
println f5()
Upvotes: 1
Views: 340
Reputation: 14519
Slightly error-prone due to variable naming being bounded to with
order, but it is something:
class Util {
static foo(arg) { "foo $arg" }
static bar() { "bar" }
static batman(fn) { fn("captain") }
}
def (foo, bar, batman) = Util.with { [it.&foo, it.&bar, it.&batman] }
assert foo("eck") == "foo eck"
assert batman(foo) == "foo captain"
Handling the script's own binding
using reflection on Util
class is also an option if you always use scripts.
Upvotes: 1
Reputation: 50245
You can have the MethodClosure
defined as a private static property of the class Utils
like:
import org.codehaus.groovy.runtime.MethodClosure
public final class Utils {
private static final MethodClosure fooPointer = this.&foo
private Utils() { }
static foo() { 42 }
}
// Client
import static Utils.*
def f1 = fooPointer
println f1()
Do not know how will it be advantageous anyway.
Upvotes: 0