2011-07-04 3 views
5

Groovy 사용 1.8. 개체 당 속성을 캐시 할 동적 클래스 정의를 만들려고합니다. 객체에 속성을 추가하지 않고 propertyMissing을 사용했습니다. 속성을 캐싱하는 것이 더 효율적이라고 생각합니다. 권리?객체 당 Groovy 동적 속성

각 인스턴스마다 고유 한 속성이 있어야합니다.

아래 코드는 잘 작동 :

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

def x = new C() 
x.prop 

출력됩니다 :

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

나는이시키는 문제에해야하는 경우 :

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 

A를 들어, 내가 "으로까지 얻을 새 속성 만들기 ", this.metaClass."$name" = "Dyna prop $name" 줄은 다음과 같이 실패합니다 : No such property: p1 for class at line 5

뭐가 잘못 되었나요?

답변

8

당신이 원하는 일을해야이 코드 :

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 

출력 그건 :

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

ExpandoMetaClass는 초기화 또는 인스턴스 변수 (적어도 1.6 이상은 아래 참조)를 사용한 후에 실제로 사용하도록 설계되지 않았습니다.

아마도 Runtime mixins을 사용하고 싶을 것입니다. 자세한 내용은 herehere입니다.

blogpost을 읽어 볼 수도 있습니다.이 임시 해결책은 런타임에 속성을 정의하기 위해 제공됩니다. 그리고 그것에 관련된 groovy bug (그건 정말 버그가 아닙니다)과 관련이 있습니다.()가 호출 는 기본 방법으로

만 초기화하기 전에 추가 할 수 로 사용할 수 있습니다 :

나는 코멘트 섹션에서 본 적어도 버전 1.6 ExpandoMetaClass 문서에서 확인. 즉, 새 ExpandoMetaClass를 만들고 일부 메서드 을 추가 한 다음 initialize()를 호출합니다. initialize() 이후에 새 메서드를 추가하려고하면 오류가 발생합니다.

+0

아하 .. 컴파일 할 때만 그렇게 할 수 있습니다. 너무 나 빠졌습니다. – Ayman

+0

런타임에 런타임 믹스를 사용할 수 있습니다. – Manny

+0

"blogpost"링크 끊김 수정 : http : // blog.enfranchisedmind.com/2008/06/groovy-metaclass-bug/ –

6

왜 간단한의 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" 

이의 표준 예입니다 http://groovy.codehaus.org/Using+methodMissing+and+propertyMissing

참고 누락하지 않을 경우,이 방법은되지 않을 것 ... 속성이 정말없는 경우 확인하지 않아도 처음에는 전화 했어.