2011-07-04 16 views
5

ग्रोवी 1.8 का उपयोग करना। मैं गतिशील वर्ग परिभाषा बनाने की कोशिश कर रहा हूं जो प्रति ऑब्जेक्ट को कैश करेगा। मैंने ऑब्जेक्ट में संपत्ति को जोड़ने के बिना propertyMissing का उपयोग किया था। मुझे लगता है कि गुणों को कैशिंग करना अधिक कुशल होगा। सही?ग्रोवी गतिशील संपत्ति प्रति ऑब्जेक्ट

ध्यान दें कि प्रत्येक उदाहरण के लिए अपने स्वयं के विभिन्न गुणों होना आवश्यक है।

कोड के नीचे ठीक काम करता है:

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 उपयोग करना चाहते हैं। अधिक जानकारी here और here

आप एक blogpost है, जो एक वैकल्पिक हल रनटाइम पर गुण को परिभाषित करने के प्रदान की जाती है पढ़ सकते हैं। और संबंधित groovy bug (यह वास्तव में एक बग नहीं है) इससे संबंधित है।

मैं टिप्पणी अनुभाग में देखा और सत्यापित कम से कम संस्करण 1.6 ExpandoMetaClass दस्तावेज में:

डिफ़ॉल्ट तरीकों से केवल की अनुमति दी जाती प्रारंभ से पहले जोड़ा जाना() कहा जाता है। दूसरे शब्दों में आप नया ExpandoMetaClass बनाते हैं, कुछ विधियां जोड़ें और फिर प्रारंभ करें() को कॉल करें। यदि आप प्रारंभ करने के बाद नई विधियों को जोड़ने का प्रयास करते हैं() को त्रुटि फेंक दिया जाएगा।

+0

अहा .. आप केवल कि संकलन समय पर .. बहुत बुरा कर सकते हैं। – Ayman

+0

आप रनटाइम – Manny

+0

के लिए रनटाइम मिश्रण का उपयोग कर सकते हैं "ब्लॉगपोस्ट" टूटी हुई लिंक को ठीक करना: http: // ब्लॉग।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

ध्यान दें, आप अगर संपत्ति वास्तव में याद आ रही है की जाँच की ज़रूरत नहीं है ... अगर यह वंचित नहीं रहेंगे, विधि नहीं होगा पहली जगह में बुलाया जाता है।

संबंधित मुद्दे