2013-03-19 10 views
5

Mam ścieżkę dla obiektu wewnątrz obiektu w obiekcie i chcę go ustawić za pomocą dynamicznych zdolności Groovy. Zwykle można to zrobić, wykonując następujące czynności:Groovy: Ustaw dynamiczną metodę zagnieżdżoną, używając ciągu jako ścieżki

class Foo { 
    String bar 
} 


Foo foo = new Foo 
foo."bar" = 'foobar' 

To działa poprawnie. Ale co, jeśli masz zagnieżdżone obiekty? Coś jak:

class Foo { 
    Bar bar 
} 

class Bar { 
    String setMe 
} 

Teraz chcę użyć dynamicznej ustawienie, ale

Foo foo = new Foo() 
foo."bar.setMe" = 'This is the string I set into Bar' 

Zwraca MissingFieldException.

Jakieś wskazówki?

AKTUALIZACJA: Dzięki Timowi za wskazanie mi we właściwym kierunku, początkowy kod działa dobrze w pobieraniu właściwości, ale muszę ustawić wartość za pomocą ciągu ścieżki.

Oto co wymyśliłem ze strony Tim sugerowanej:

def getProperty(object, String propertyPath) { 
    propertyPath.tokenize('.').inject object, {obj, prop -> 
     obj[prop] 
    } 
    } 

    void setProperty(Object object, String propertyPath, Object value) { 
    def pathElements = propertyPath.tokenize('.') 
    Object parent = getProperty(object, pathElements[0..-2].join('.')) 
    parent[pathElements[-1]] = value 
    } 
+1

http: //stackoverflow.com/questions/5488689/how-to-retrieve-nested-properties-in-groovy –

+0

Udało mi się zrealizować to zadanie, opierając się na metodzie getProperty i korzystam z niej, a powyższą odpowiedź zamieszczę od czasu komentarza sekcja nie jest zbyt dobra, aby umieścić kod w –

Odpowiedz

1

Obserwuje działa poprawnie.

foo."bar"."setMe" = 'This is the string I set into Bar'; 

Bez getProperty nadrzędne można osiągnąć ten sam efekt przy użyciu "$ {}" składnia GString jak poniżej kod demonstruje

class Baz { 
    String something 
} 

class Bar { 

    Baz baz 

} 

class Foo { 
    Bar bar 
} 

def foo = new Foo() 
foo.bar = new Bar() 
foo.bar.baz = new Baz() 

def target = foo 
def path = ["bar", "baz"] 
for (value in path) { 
    target = target."${value}" 
} 

target."something" = "someValue" 
println foo.bar.baz.something 

końcowe wydruki println "SomeValue" zgodnie z oczekiwaniami

+1

Tylko mały dodatek do tej znakomitej odpowiedzi dla innych, aby uniknąć potknięcia się o to: Musisz wyraźnie użyć "podwójnych cudzysłowów", aby to zadziałało, ponieważ w ten sposób zdefiniowane są GStrings (z wyrażeniami w środku). Ale domyślam się, że wszyscy, którzy jesteście programistami, już to wiedzieli :) – kaskelotti

Powiązane problemy