phanin
phanin

Reputation: 5487

How to pass a method as a Binding variable to Groovy's ConfigSlurper?

I was able to bind an object on Groovy's ConfigSlurper but not a method. Is that not possible?

Here's an example

String conf = """

k1 = "v1"

environments{

    prod{
         person.create("prod.id1"){
            name = "prod.name1"
        }
    }

    dev {
        person.create("dev.id1"){
            name = "dev.name1"
        }

    }
}

environments{

    prod{
         create("prod.id2"){
            name = "prod.name2"
         }

    }

    dev {
        create("dev.id2"){
            name = "dev.name2"
        }


    }
}


"""

def parser = new ConfigSlurper("prod")
Person person1 = new Person()
Person person2 = new Person()
parser.setBinding([person: person1, // <-- SUCCESS
                   create: person2.&create]) // <-- NOT SUCCESS?

println parser.parse(conf)
println "person1=${person1.dump()}"
println "person2=${person2.dump()}"


class Person{

    String id
    String name

    public void create(String id, Closure c){
       this.id = id
       this.with(c)
    }


}

Output is

[k1:v1, create:prod.id2, create.name:prod.name2]
person1=<Person@409b0772 id=prod.id1 name=prod.name1>
person2=<Person@205ee81 id=null name=null>

Please ignore any design flaws in the example.

Upvotes: 2

Views: 1313

Answers (1)

Dany
Dany

Reputation: 1530

person.create(...) is translated by Groovy to getProperty('person').invokeMethod('create', ...), it works since person is defined in the binding and create is defined on object returned by getProperty('person').

create.call(...) works because it's translated to getProperty('create').invokeMethod('call', ...). create property is defined via binding and it is of MethodClosure type which has call method defined.

However create(...) is translated to invokeMethod('create', ...). It fails because there is no method create and you cannot define methods via binding.

Upvotes: 2

Related Questions