2011-08-16 104 views
1

我有以下代碼:Groovy的:動態地將屬性添加到從內部類方法Groovy類

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(); 

在myClass.myProperty,Missing property myProperty印出到控制檯。

但隨後myClass.myMethod(),常規並沒有試圖去propertyMissing而只是拋出一個

groovy.lang.MissingPropertyException: No such property: variable for class: MyClass 

一些網上搜索表明,這是因爲myClass.myProperty調用一個getter方法,其重定向到propertyMissing。

我猜測,在類方法中,groovy不通過getter方法獲取變量,這就是爲什麼propertyMissing沒有被調用?

有沒有辦法通過使用動態propertyMissinggetProperty或類似的東西來實現我想要做的事情?

P.S.我不想在myMethod中執行def variable = ...String variable = ...。我希望myMethod內的語法保持爲variable = ...,但在該方法之外添加任何內容都是可以接受的。

+0

爲什麼groovy在執行'myClass.myMethod();時拋出一個錯誤;'當關鍵字'def'或任何數據類型關鍵字如'string'缺少時? –

+1

我相信只有在腳本中運行它時,您纔可以設置變量而不需要定義或聲明它。當你在腳本中運行它時,如果沒有定義或聲明,那麼這個變量會被放到腳本的Binding中(當你在腳本中時,你可以用getBinding()調用來訪問它)。但是,當您沒有運行腳本時,並沒有「綁定」,並且Groovy希望您使用def或使用數據類型來聲明它。 – user872831

+1

http://groovy.codehaus.org/Scoping+and+the+Semantics+of+%22def%22 – user872831

回答

11

你可以讓你的類extend ExpandoExpando 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 

您可以手工卷創建變量自己的後盾地圖,並寫get/setProperty方法自己一個類似的功能,即:

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 

雖然從source code for Expando可以看出,這款手卷版本的檢查工作量少得多,我相信它少了;-)

+1

完美的作品,謝謝!實際上,我在使用getProperty之前......但忘記了我正在嘗試設置(未獲取)屬性並未實現setProperty ...但您對Expando的使用方式甚至更好。 =]接受爲答案 – user872831