Call a method as a closure

My understanding of the Groovy .& Operator is that it converts a method call to a closure. Therefore, it seems that the following code (which can be run in the Groovy console ) should work:

 class Foo { def method(def param) { param + 10 } } def invokeClosure = {Closure closure -> return closure.call() } def f = new Foo() invokeClosure f.&method(6) 

Of course, if I change the last line to

 invokeClosure {f.method(6)} 

it works fine, but what is wrong with my understanding of the operator .& ?

Thanks Don

+6
closures groovy
source share
3 answers

When converting a method to closure using a notation . & you do not consider parameters. f. & method (6) is the same as calling f.method (6), which will return 16, so in your example you pass 16 to invokeClosure, not to closure. This throws the following exception because the Integer class does not have a call method:

Exception: missing method signature: java.lang.Integer.call ()

The method pointer for f.method in invokeClosure is passed below and will be what you normally use. &.

 class Foo { def method(def param) { param + 10 } } def invokeClosure = {Closure closure -> return closure.call(6) // can leave off .call } def f = new Foo() invokeClosure f.&method 

As you indicated, the following will work:

 invokeClosure {f.method(6)} 

This is because you go through a closure that takes no parameters, so the clos.call () function works in this case.

+8
source share

Use invokeClosure f.&method.curry(6) instead. This is a closure that could be called without parameters

+1
source share

The above example can also be extended to accept a parameter as an argument in invokeClosure. This will give you the expected result and syntax.

 class Foo { def method(def param) { param + 10 } } def invokeClosure = {Closure closure, def parameter -> return closure.call(parameter) } def f = new Foo() invokeClosure f.&method, 6 
0
source share

All Articles