I have the following code:
class MyClass {
def myMethod() {
variable = "I am a variable"
}
def propertyMissing(String name) {
println "Missing property $name"
}
}
MyClass myClass = new MyClass();
myClass.myProperty
myClass.myMethod();
At myClass.myProperty, Missing property myProperty
was printed out to the console.
But then in myClass.myMethod()
, groovy makes no attempt to go to propertyMissing
but instead just throws a
groovy.lang.MissingPropertyException: No such property: variable for class: MyClass
Some search online indicates that it is because myClass.myProperty
calls a getter method, which redirects to propertyMissing.
I am guessing that within class methods, groovy doesn't go thr开发者_StackOverflowough getter methods for variables and that's why propertyMissing is not getting called?
Is there a way to achieve what I want to do using the dynamic propertyMissing
, or getProperty
, or anything like that?
P.S. I don't want to do def variable = ...
or String variable = ...
in myMethod. I am hoping that the syntax within myMethod
will stay as variable = ...
, but adding anything outside of that method is acceptable.
You can make your class extend Expando
(Expando is described here)
class MyClass extends Expando {
def myMethod() {
variable = "I am a variable"
}
def propertyMissing(String name) {
println "Missing property $name"
}
}
MyClass myClass = new MyClass()
myClass.myProperty
myClass.myMethod()
println myClass.variable
You can hand-roll a similar functionality by creating your own backing map for variables, and writing the get/setProperty
methods yourself, ie:
class MyClass {
def myMethod() {
variable = "I am a variable"
}
def propertyMissing(String name) {
println "Missing property $name"
}
def backingMap = [:]
Object getProperty( String property ) {
if( backingMap[ property ] == null ) {
propertyMissing( property )
}
else {
backingMap[ property ]
}
}
void setProperty( String property, Object value ) {
backingMap[ property ] = value
}
}
MyClass myClass = new MyClass()
myClass.myProperty
myClass.myMethod()
println myClass.variable
Though as you can see from the source code for Expando, this hand-rolled version does a lot less checks and I'd trust it less ;-)
精彩评论