mhshams
mhshams

Reputation: 16972

groovy: how to pass varargs and closure in same time to a method?

Given following groovy function:

def foo(List<String> params, Closure c) {...}

The method call would be:

foo(['a', 'b', 'c']) { print "bar" }

But I would like to get rid of brackets (List) in the function call. something like:

foo('a', 'b') { print "bar" }

I cannot change the list parameter to varargs because varargs can be only the last parameter in function (here the closure is the last one).

Any suggestion?

Upvotes: 16

Views: 22805

Answers (4)

C.A.B.
C.A.B.

Reputation: 583

Switch to Kotlin ;-)

fun test(vararg s: String, c: ()->String) {
    println(s)
    println(c())
}

Working like a charm...

Upvotes: -8

Tobia
Tobia

Reputation: 18821

There's always Poor Man's Varargs™

def foo(String p1,                                  Closure c) {foo [p1],             c}
def foo(String p1, String p2,                       Closure c) {foo [p1, p2],         c}
def foo(String p1, String p2, String p3,            Closure c) {foo [p1, p2, p3],     c}
def foo(String p1, String p2, String p3, String p4, Closure c) {foo [p1, p2, p3, p4], c}
...

I'm only half joking.

Upvotes: 9

Gregor Petrin
Gregor Petrin

Reputation: 2931

Seeing that it's impossible to achieve exactly what you want (it's written in Groovy documentation that your specific case is a problem, unfortunately they are migrating the docs so I can't directly link right now), what about something along these lines:

def foo(String... params) {
    println params
    return { Closure c ->
        c.call()
    }
}

foo('a', 'b') ({ println 'woot' })

Now you need to put the closure in parantheses, but you don't need to use an array anymore..

Upvotes: 14

Victor
Victor

Reputation: 5131

I think this only could be possible if you use an array as argument or an Variable-Length Argument List :

def foo(Object... params) {
    def closureParam = params.last()
    closureParam()
}

foo('a', 'b') { print "bar" }

Upvotes: 11

Related Questions