rascio
rascio

Reputation: 9279

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?

Upvotes: 13

Views: 22639

Answers (2)

epidemian
epidemian

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

Dave Newton
Dave Newton

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

Related Questions