Reputation: 9279
I would like to write a method that take a Closure as argument and pass to it tow arguments, but who write that closure can specify one or two arguments as he prefer
I tried in this way:
def method(Closure c){
def firstValue = 'a'
def secondValue = 'b'
c(firstValue, secondValue);
}
//execute
method { a ->
println "I just need $a"
}
method { a, b ->
println "I need both $a and $b"
}
If I try to execute this code the result is:
Caught: groovy.lang.MissingMethodException: No signature of method: clos2$_run_closure1.call() is applicable for argument types: (java.lang.String, java.lang.String) values: [a, b]
Possible solutions: any(), any(), dump(), dump(), doCall(java.lang.Object), any(groovy.lang.Closure)
at clos2.method(clos2.groovy:4)
at clos2.run(clos2.groovy:11)
How can I do it?
Upvotes: 13
Views: 22639
Reputation: 19229
You can ask for the maximumNumberOfParameters
of the Closure before calling it:
def method(Closure c){
def firstValue = 'a'
def secondValue = 'b'
if (c.maximumNumberOfParameters == 1)
c(firstValue)
else
c(firstValue, secondValue)
}
//execute
method { a ->
println "I just need $a"
}
method { a, b ->
println "I need both $a and $b"
}
Output:
I just need a
I need both a and b
Upvotes: 33
Reputation: 160301
The simplest is to give it a default value:
method { a, b=nil ->
println "I just need $a"
}
You can also use an array:
method { Object[] a ->
println "I just need $a"
}
Upvotes: 3