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...
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With