I’m working on a driver and library and have discovered that it appears to not be allowed to have variable args for a closure. For example, adding the following line of code:
def x = { ...args -> log.debug("${args}") }
Results in the following compilation error when trying to save a driver:
Importing [[Ljava.lang.Object;] is not allowed
Is this a bug or an intentional sandbox security measure? Is there any way to work around it without knowing the number of arguments in advance?
I am sure they are possible in a closure for an async HTTP call, not sure about more generally. Perhaps @thebearmay or one of the other developers would know…?
Without the ... it compiles, with the ... it fails. Might need to see a bit more code to determine what you are attempting.
Thanks for checking too.
Its mainly for syntactic sugar - wanting the ability to have a generic bit of library code that can pass through a variable number of args and then have the receiving closure in the driver code able to handle single or multiple return values without having to write extra lines of code to unpack/destructure the arguments from an array or list, e.g.
import groovy.transform.Field
@Field static Map requestHandlers = [:]
def getReadings(id, qty, Closure onReading) {
requestHandlers[id] = onReading
sendANetworkRequestToGetReadings(id, qty)
}
def parse_network_response(msg) {
def response = unpack_response(msg)
def id = response.id
List readings = response.readings
Closure handler = requestHandlers[id]
requestHandlers.remove(id)
handler(*readings)
}
So syntactically its nice to use because you can do:
getReadings(ID, 1, { singleReading -> do something with it })
or:
getReadings(ID, 3, { a, b, c -> do something with them })
getReadings(ID, N, { ...multipleReadings -> do something with them })
The actual code is unhelpfully much more complex hence not providing that here.
I can work around by passing a single argument containing the list of results; but I was hoping to do something syntactically nicer like the above.
Maybe restructure a little to make it work like:
def countArgs(args) {
log.debug "You passed ${args.size()} arguments."
args.each {
log.debug "${it.key}:${it.value}"
}
}
...
args = [1:"test"]
countArgs(args)
args = [1:"test", 2:"test2", 3:"test3"]
countArgs(args)
1 Like