Groovy: динамически добавлять свойства в классы Groovy из методов класса - PullRequest
1 голос
/ 16 августа 2011

У меня есть следующий код:

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() groovy не предпринимает попытокперейти на propertyMissing, но вместо этого просто выдает

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

Некоторые результаты поиска в Интернете указывают, что это происходит потому, что myClass.myProperty вызывает метод получения, который перенаправляет на propertyMissing.

Я предполагаючто в методах класса groovy не проходит через методы getter для переменных, и поэтому propertyMissing не вызывается?

Есть ли способ достичь того, что я хочу сделать, используя динамический propertyMissing или getProperty, или что-то в этом роде?

PS Я не хочу делать def variable = ... или String variable = ... в myMethod.Я надеюсь, что синтаксис в myMethod останется variable = ..., но добавление чего-либо вне этого метода приемлемо.

1 Ответ

11 голосов
/ 16 августа 2011

Вы можете сделать свой класс extend Expando ( Расширение описано здесь )

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

Хотя, как вы можете видеть из исходного кода для Expando , эта свернутая вручную версия выполняет намного меньше проверок, и я бы ей меньше доверял; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...