2011-07-04 9 views
5

Używanie Groovy 1.8. Próbuję utworzyć dynamiczną definicję klasy, która będzie właściwości pamięci podręcznej dla każdego obiektu. Użyłem propertyMissing bez dodawania właściwości obiektu do porządku. Po prostu myślę, że buforowanie właściwości byłoby bardziej efektywne. Dobrze?Dynamiczna właściwość Groovy na obiekt

Należy pamiętać, że każda instancja musi mieć swoje własne właściwości.

Poniższy kod działa poprawnie:

class C {} 
def c = new C() 
c.metaClass.prop = "a C property" 
println c.prop 

def x = new C() 
x.prop 

wyjście wola:

a C property 
groovy.lang.MissingPropertyException: No such property: prop for class: C 

Jeśli muszę to problemowo:

class A { 
    def propertyMissing(String name) { 
     if(!this.hasProperty(name)) { 
      println "create new propery $name" 
      this.metaClass."$name" = "Dyna prop $name" 
      println "created new propery $name" 
     } 
     this.metaClass."$name" 
    } 
} 

a = new A() 
println a.p1 

Dla A, mam w miarę " utwórz nową właściwość ", ale linia this.metaClass."$name" = "Dyna prop $name" kończy się niepowodzeniem z: No such property: p1 for class at line 5

Co jest nie tak?

Odpowiedz

8

Ten kod powinien robić to, co chcesz:

class A { 
    A() { 
    def mc = new ExpandoMetaClass(A, false, true) 
    mc.initialize() 
    this.metaClass = mc 
    } 

    def propertyMissing(String name) { 
    println "create new propery $name" 
    def result = "Dyna prop $name" 
    this.metaClass."$name" = result 
    println "created new propery $name" 
    result 
    } 
} 

a = new A() 
println a.p1 
println a.p1 

która wyprowadza:

create new propery p1 
created new propery p1 
Dyna prop p1 
Dyna prop p1 
1

ExpandoMetaClass naprawdę nie jest przeznaczony do stosowania po inicjalizacji lub zmienne instancji (patrz poniżej odniesienia przynajmniej 1,6 lub więcej).

Może chcesz użyć Runtime mixins. Więcej informacji: here i here.

Możesz przeczytać blogpost, który jest dostarczany obejście zdefiniować właściwości w czasie wykonywania. I związane z nim groovy bug (to nie jest błąd).

widziałem w komentarzach i weryfikowane przynajmniej w wersji dokumentacji 1.6 ExpandoMetaClass:

Sposobami domyślne są dozwolone tylko do zostać dodana przed zainicjować() jest nazywa. Innymi słowy, tworzymy nowy ExpandoMetaClass , dodamy niektóre metody , a następnie wywołujemy metodę initialize(). Jeśli spróbujesz dodać nowe metody, po wywołaniu initialize(), zostanie zgłoszony błąd .

+0

Aha .. Możesz to zrobić tylko w czasie kompilacji .. szkoda. – Ayman

+0

Możesz użyć komponentu Runtime dla runtime – Manny

+0

Naprawianie uszkodzonego linku "blogpost": http: // blog.enfranchisedmind.com/2008/06/groovy-metaclass-bug/ –

6

Dlaczego nie można przechowywać swoje właściwości dynamicznych w prosty HashMap?

class Foo { 
    def storage = [:] 
    def propertyMissing(String name, value) { storage[name] = value } 
    def propertyMissing(String name) { storage[name] } 
} 
def f = new Foo() 
f.foo = "bar" 

Jest to standardowy przykład z: http://groovy.codehaus.org/Using+methodMissing+and+propertyMissing

Uwaga, nie trzeba by sprawdzić, czy nieruchomość jest naprawdę brakuje ... jeśli nie będzie brakowało, metoda nie będzie wezwany w pierwszej kolejności.

Powiązane problemy