Reputation: 101
I am experimenting with Groovy closures and delegates right now. I have the following code setting the delegate of a closure to another class, which works perfectly fine.
def closure = {
newMethod()
};
closure.setDelegate(new MyDelegate());
closure.setResolveStrategy(Closure.DELEGATE_ONLY);
closure();
class MyDelegate {
public void newMethod() {
println "new Method";
}
}
This prints out "new Method", showing that newMethod() in MyDelegate is actually called. Now I am trying to do the same with MethodClosure.
public class TestClass {
public void method() {
newMethod();
}
}
TestClass a = new TestClass();
def methodClosure = a.&method;
methodClosure.setDelegate(new MyDelegate());
methodClosure.setResolveStrategy(Closure.DELEGATE_ONLY);
methodClosure();
class MyDelegate {
public void newMethod() {
println "new Method";
}
}
However, this time, I get the following exception: Exception in thread "main" groovy.lang.MissingMethodException: No signature of method: TestClass.newMethod() is applicable for argument types: () values: [].
So for this methodClosure, it doesn't seem like it's going to the delegate for method lookup at all. I have a feeling this is probably intended behavior, but are there ways to actually use delegates for MethodClosures?
Thanks alot.
Upvotes: 3
Views: 1421
Reputation: 66109
MethodClosures are actually just adapters for calling methods with through the Closure interface. It doesn't do delegation, as you've seen.
One way to use MyDelegate as a delegate would be to mix it in, like so:
TestClass a = new TestClass()
a.metaClass.mixin MyDelegate
def methodClosure = a.&method
methodClosure()
// or skip the closure altogether
TestClass b = new TestClass()
b.metaClass.mixin MyDelegate
b.method()
Upvotes: 2