'Groovy closure without preceding equal sign prop = {} vs prop {}

I'm trying to create a config file for my java app that can have lazy evaluation, for instance, contain an e-mail template with current date time. I use ConfigSlurper to parse the config file.

For some reason I can't find at https://groovy-lang.org/closures.html the description of the commonly used form (see build.gradle): prop1 { ... } prop2 { ... }. Am I looking at the wrong place?

My tests show that such closures are evaluated immediately and the example above can be rewritten as: prop1 = { ... }() prop2 = { ... }() (notice the parentheses, without them the evaluation is lazy).

I also don't understand why using dots in property without the equal sign cause MissingMethodException: No signature of method: groovy.util.ConfigObject.URL() if I use: server.URL { System.out.println('ccc'); 'asd' } in the example below.

It's disappointing that the choice is completely transparent for Groovy, but you have to check that a value is instance of Closure or GString when using java.

I used this article as the starting point https://blog.mrhaki.com/2009/08/grassroots-groovy-configuration-with.html

// We can group settings.
// The following settings are created:
// app.version, app.setting1, app.setting2, app.setting3, app.date, app.active
app {
    System.out.println('aaa')
    version = "1.0"
     
    // We can write code to set up settings.
    [1, 2, 3].each {
        this."setting${it}" = it * 10
    }
     
    // We can use Java objects
    date = new Date()
    active = true
}
 
server.URL = "http://default"
 
// Environment specific settings override settings with the
// same name.
environments {
    development {
        server = { System.out.println('ccc'); 'asd' }
//        server.URL = "${-> System.out.println('bbb');new Date()}http://localhost"
    }
    test {
        server.URL = 'http://test:9080'
    }
    integrationtest {
        server.URL = 'http://integrationtest/url'
    }
    production {
        server.URL = 'http://prod/url'
    }
}


Solution 1:[1]

My tests show that such closures are evaluated immediately and the example above can be rewritten as: prop1 = { ... }()

Closures are not evaluated immediately. The parens above are causing the closure to be evaluated.

For some reason I can't find at https://groovy-lang.org/closures.html the description of the commonly used form (see build.gradle): prop1 { ... } prop2 { ... }.

prop1 {} is invoking a method named prop1 and passing a closure as a parameter That code is equivalent to this:

def myClosure = {}

prop1(myClosure)

I also don't understand why using dots in property without the equal sign cause MissingMethodException: No signature of method: groovy.util.ConfigObject.URL()

Something like server.URL = 'http://test:9080' is assigning a value (http://test:9080) to a property (server.URL). If you remove the equal sign you are changing the expression fundamentally and then would be invoking a method named URL on an object named server and passing http://test:9080 as a parameter.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jeff Scott Brown