Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

groovy method that take closure with one or two arguments

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?

like image 965
rascio Avatar asked Aug 22 '12 16:08

rascio


People also ask

How do you make a closure on Groovy?

Closures can also contain formal parameters to make them more useful just like methods in Groovy. In the above code example, notice the use of the ${param } which causes the closure to take a parameter. When calling the closure via the clos. call statement we now have the option to pass a parameter to the closure.

What is a closure in Groovy?

A closure in Groovy is an open, anonymous, block of code that can take arguments, return a value and be assigned to a variable. A closure may reference variables declared in its surrounding scope.

How do I use lambda expression in Groovy?

The Groovy syntax doesn't support the lambda expressions, but we can rely on closure coersion to use Groovy closures as Java lambda expressions in our code. In the following sample we use the Java Streams API. Instead of lambda expressions for the filter and map methods we use Groovy closures.

What is inject in Groovy?

In Groovy, the inject() method is one of the cumulative methods that allows us to add (or inject) new functionality into any object that implements the inject() method. In the case of a Collection, we can apply a closure to a collection of objects uniformly and then collate the results into a single value.


1 Answers

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
like image 134
epidemian Avatar answered Sep 30 '22 16:09

epidemian