Reputation: 7642
I am trying to understand groovy better and came across this usage.
Found this while using Http-Builder, though my question is independent of that - I am mainly interested in finding the "groovy-way" for the general use-case implied.
There is an existing "request" method that takes a closure and when the http-builder invokes that closure it passes it one parameter, the "request". What is the best way to get additional information passed in to such a closure?
Following normal usage, the code might look something like:
myHttpClient.request(POST) { req ->
uri.path = 'some path'
uri.query = [ p1:'value1', p2:'value2' ]
....
}
In this example, I would like to be able to dynamically set (or pass in) three values - the path, and the values for the query parameters 1 & 2.
I don't know enough to know the right way, but have done something like this:
EDIT cleaned up the code
def myPath = '/a/b/c'
def p1Param = 'p1Value'
def p2Param = 'p2Value'
def myClosure = { req ->
uri.path = myPath
uri.query = [ p1:p1Param, p2:p2Param ]
....
}
// first call:
myHttpClient.request(POST, myClosure)
// later on:
myPath = '/new/path'
p1Param = 'newValue1'
p2Param = 'newValue2'
myHttpClient.request(POST, myClosure)
While this works and is DRY, it is also ugly and I think/hope there is a better way. I also thought about putting the entire call into its own closure and simply calling that - again I was hoping there is a better way!
Upvotes: 1
Views: 149
Reputation: 5909
Just to add another option, you could use currying.
Groovy - Closures formal definition
What you would do is a closure that takes 4 parameters like:
def reqClosure = { path, p1, p2, req ->
uri.path = path
uri.query = [ p1: p1, p2: p2 ]
...
}
Then you would call the httpClient currying the first 3 parameters of the closure:
myHttpClient.request POST, reqClosure.curry('/new/path', 'value1', 'value2')
Upvotes: 2
Reputation: 171054
You could write a closure that returns a closure:
def reqClosure = { path, p1, p2 ->
{ req ->
uri.path = path
uri.query = [ p1: p1, p2: p2 ]
...
}
}
And then call httpClient like so:
myHttpClient.request( POST ) reqClosure( '/new/path', 'value1', 'value2' )
Upvotes: 2