Reputation: 181
In Config.groovy:
Query {
parameterMap {
time.'1328' = ['T1']
time.'1329' = ['T2']
templates.'T1' = ['X','Y','Z']
templates.'T2' = ['Z']
}
}
In QuartzSchedulerJob I want to use T1
and T2
which are templateId
as key to get the corresponding values in parameterMap
but it returns me null
and [:]
respectively, parameterMap.templates.get("${v}")
but I want to get ['X','Y','Z']
and ['Z']
respectively for T1
and T2
def execute() {
def currentTime = new Date().format('HHmm')
grailsApplication.config.Query.parameterMap.time.each { k, v ->
if (currentTime=="${k}") {
println "${k} " + currentTime
String templateId = "${v}".replaceAll("\\[", "").replaceAll("\\]","")
println grailsApplication.config.Query.parameterMap.templates.get("${v}") //this prints null
println grailsApplication.config.Query.parameterMap.templates.getAt("${v}") //this prints [:]
}
}
}
Upvotes: 0
Views: 288
Reputation: 75671
"${k}"
is a weird expression, and I see it a lot in Groovy code. I would love to know who and/or what (book/blog/???) somehow got people using that syntax. I see it quite often in toString
methods that intend to return a class field as the value, e.g.
private String name
...
String toString() {
"${name}"
}
Why not just return the variable?
String toString() {
name
}
You're doing this here, making a GString
"${k}"
with only a single embedded variable and no other characters, and then implicitly converting it to a String when comparing it to currentTime
(which works, but is far from optimal or sensible) and using this GString
to generate (in a very funky way) to a potential key in a Map
when calling get
and getAt
, and wondering why the value inside this weird little GString
, which is very close to being a map key (as Tim points out the values of the time
map are single-element List
s, and the keys of the templates
map are String
s which are the single elements of these List
s) isn't also automagically converted into what you wanted it to have been.
Groovy does lots of implicit conversions, but the signature of the get
method in Map
is Object get(Object key)
(technically it's got a generic return type, but that's not relevant here) so Groovy isn't going to do any conversion for you - you're passing an Object
as a parameter to a method that takes Object
. There's no reason at all to expect that it would be converted to a String, or to any of the types of any of the keys, or to anything at all.
This loc hurts my brain:
String templateId = "${v}".replaceAll("\\[", "").replaceAll("\\]","")
You're taking the list v
, converting it to a String
by embedding it with nothing else in a GString
, coercing Groovy to convert the GString
to a String
so it can call replaceAll
on it, to remove the brackets that are at the beginning and end of the toString
form of AbstractCollection
, to extract the single String
element in v
.
How about something a bit more direct:
String templateId = v[0]
and its use in a cleaned up version of execute
:
def execute() {
String currentTime = new Date().format('HHmm')
grailsApplication.config.Query.parameterMap.time.each { k, v ->
if (currentTime == k) {
println "$k $currentTime"
String templateId = v[0]
println config.Query.parameterMap.templates[templateId] // get and getAt would also work
}
}
}
Upvotes: 1