Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically add a property to a closure in Groovy?

Tags:

groovy

My environment is Groovy Version: 2.5.1 JVM: 1.8.0_151

As you know, you can dynamically add a property or method to a class like this:

class Cat {
}

def cat = new Cat()

cat.metaClass.name = "Amy"
cat.metaClass.greet = { println "Hello"}

println cat.name
cat.greet()

It runs OK. But when it comes to a closure like this:

def cat = {}

cat.metaClass.name = "Amy"
cat.metaClass.greet = { println "Hello"}

println cat.name
cat.greet()

It gives errors like this:

Caught: groovy.lang.MissingPropertyException: No such property: name for class: org.codehaus.groovy.runtime.metaclass.ClosureMetaClass groovy.lang.MissingPropertyException: No such property: name for class: org.codehaus.groovy.runtime.metaclass.ClosureMetaClass at test.run(test.groovy:7)

Why? The closure is also an object in Groovy...

like image 735
Andy Xiao Avatar asked Sep 02 '25 10:09

Andy Xiao


2 Answers

Groovy uses a specific form of metaclass for closures called "ClosureMetaClass" as seen by your error, or by this snippet:

    def t = {}
    def t2 = new Object()

    println t.metaClass.class.simpleName // ClosureMetaClass
    println t2.metaClass.class.simpleName // HandleMetaClass

this happens because within the language itself, Groovy has a specific method which returns a MetaClass depending on the Classtype passed, with the signature :

MetaClass getMetaClass(Class var1);

Taking a look at groovy's official documentation, the ClosureMetaClass is for "internal usage only". Hence you're unable to add any methods to it during the runtime.

You would be able to add methods to the metaClass of the Closure class itself. See here.

Remove metaClass.

I ran this locally and it worked. I'm still learning groovy myself, so I don't know why it works. I imagine it is due to a basic closure does not having metaClass information.

def cat = {}

cat.name = "Amy"
cat.greet = { println "Hello"}

println cat.name
cat.greet()
like image 25
dimwittedanimal Avatar answered Sep 05 '25 07:09

dimwittedanimal