Chris F
Chris F

Reputation: 16673

How to execute closure as value of a Groovy map?

I have the following code

#!/usr/local/homebrew/bin/groovy

def jobs = ['Groovy', 'Rocks', 'Big', 'Time']

def generateStage(String service, Integer sleepTime=0) {
    return {
          sleep sleepTime
          println "Hello $service"
    }
}

Map generateStageMap(List list) {
    Integer sleepTime = 0
    Map stageMap = [:]
    list.each {
        stageMap[it] = generateStage(it, sleepTime)
        // slightly staggered starts so we don't have too many
        // request per sec to the CLI
        sleepTime += 5
    }
    return stageMap
}

Map map = generateStageMap(jobs)
map.each {
  it.value
}

How do I make it execute the println statement so output looks like this?

Hello Groovy
Hello Rocks
Hello Big
Hello Time

Or better yet, how can I check that the generated closure contains the key. For example, in pseudo-code

map.each {
  // just sample code that conveys the idea
  assert it.value.contains(it.key)
}

Upvotes: 4

Views: 5077

Answers (1)

Szymon Stepniak
Szymon Stepniak

Reputation: 42174

Your code is missing closure invocation. The first thing worth mentioning is that the map you create is of the following type:

Map<String,Closure> map = generateStageMap(jobs)

The code you put at the end of your example does nothing.

map.each {
    it.value
}

It only "touches" the value stored in the map, but it does not invoke the closure it holds. The simplest way to get the expected output is to actually invoke the closure. You can do it by invoking call() method:

map.each {
    it.value.call()
}

or simply adding () to the end of the expression:

map.each {
    it.value()
}

Both will invoke the closures and produce the output you expect.

Upvotes: 6

Related Questions