2011-03-30 14 views
8

में नेस्टेड गुणों को कैसे पुनर्प्राप्त करें, मुझे आश्चर्य है कि ग्रोवी में नेस्टेड गुणों को पुनर्प्राप्त करने का सबसे अच्छा तरीका क्या है, एक ऑब्जेक्ट और मनमाने ढंग से "संपत्ति" स्ट्रिंग लेना। मैं कुछ इस तरह करना चाहते हैं:ग्रोवी

someGroovyObject.getProperty("property1.property2") 

मैं एक कठिन समय ऐसा करने के लिए इच्छुक अन्य लोगों का एक उदाहरण खोजने में कठिनाई हुई है, इसलिए शायद मैं कुछ बुनियादी ग्रूवी अवधारणा को समझने नहीं कर रहा हूँ। ऐसा लगता है कि ऐसा करने के लिए कुछ शानदार तरीका होना चाहिए।

संदर्भ के रूप में, विकेट में एक विशेषता है कि मैं वास्तव में क्या देख रहा हूँ है, PropertyResolver कहा जाता है: http://wicket.apache.org/apidocs/1.4/org/apache/wicket/util/lang/PropertyResolver.html

किसी भी संकेत की सराहना की होगी!

उत्तर

22

मुझे नहीं पता कि ग्रोवी के पास ऐसा करने का एक अंतर्निहित तरीका है, लेकिन यहां 2 समाधान हैं। इसका परीक्षण करने के लिए Groovy Console में इस कोड को चलाएं।

def getProperty(object, String property) { 

    property.tokenize('.').inject object, {obj, prop ->  
    obj[prop] 
    } 
} 

// Define some classes to use in the test 
class Name { 
    String first 
    String second 
} 

class Person { 
    Name name 
} 

// Create an object to use in the test 
Person person = new Person(name: new Name(first: 'Joe', second: 'Bloggs')) 

// Run the test 
assert 'Joe' == getProperty(person, 'name.first') 

///////////////////////////////////////// 
// Alternative Implementation 
///////////////////////////////////////// 
def evalProperty(object, String property) { 
    Eval.x(object, 'x.' + property) 
} 

// Test the alternative implementation 
assert 'Bloggs' == evalProperty(person, 'name.second') 
+0

यह अब मैं कम कर रहा हूं, लेकिन आपका तरीका क्लीनर है! –

+0

क्षमा करें, डॉन, आपके उत्तर को बहुत पहले स्वीकार कर लेना चाहिए था (वापस जब मुझे नहीं पता था कि मैं इस साइट पर क्या कर रहा था)। धन्यवाद ... –

+0

नोट: मैंने इन्हें एक तरह से परीक्षण किया, और इवल मेरे सिस्टम पर टोकनयुक्त संस्करण की तुलना में बहुत धीमी थी। –

2

Groovy Beans आपको सीधे फ़ील्ड तक पहुंचने दें। आपको गेटर/सेटर विधियों को परिभाषित करने की आवश्यकता नहीं है। वे आपके लिए उत्पन्न हो जाते हैं। जब भी आप एक बीन संपत्ति तक पहुंचते हैं तो गेटर/सेटर विधि को आंतरिक रूप से बुलाया जाता है। आप @ ऑपरेटर का उपयोग कर इस व्यवहार को बाईपास कर सकते हैं। निम्नलिखित उदाहरण देखें:

class Person { 
    String name 
    Address address 
    List<Account> accounts = [] 
} 

class Address { 
    String street 
    Integer zip 
} 

class Account { 
    String bankName 
    Long balance 
} 

def person = new Person(name: 'Richardson Heights', address: new Address(street: 'Baker Street', zip: 22222)) 
person.accounts << new Account(bankName: 'BOA', balance: 450) 
person.accounts << new Account(bankName: 'CitiBank', balance: 300) 

आप संग्रह के साथ काम नहीं कर रहे हैं तो आप बस सिर्फ क्षेत्र आप उपयोग करना चाहते कॉल कर सकते हैं।

assert 'Richardson Heights' == person.name 
assert 'Baker Street' == person.address.street 
assert 22222 == person.address.zip 

आप एक संग्रह के भीतर एक क्षेत्र तक पहुँचने के लिए चाहते हैं तो आप तत्व का चयन करने के लिए है:

assert 'BOA' == person.accounts[0].bankName 
assert 300 == person.accounts[1].balance​​​​​​​​​ 
+1

यह अच्छी सलाह है, लेकिन मैं एक स्ट्रिंग लेने में सक्षम होना चाहता हूं। क्या _person.address.street_ के मूल्य को वापस करने में कोई रास्ता है _person। "Address.street" _? –

+0

आप [ग्रोवी की गतिशील विधि आमंत्रण] (http://groovy.codehaus.org/Dynamic+Groovy) का उपयोग कर सकते हैं। हालांकि, आपको विधि का नाम घोषित करने की आवश्यकता है: व्यक्ति। "GetAddress"()। "GetStreet"()। –

+0

जानकारी और लिंक के लिए धन्यवाद ... मैं इसके बारे में पढ़ूंगा और देख सकता हूं कि यह यहां मदद कर सकता है या नहीं। –

1

के हिस्से के रूप में उपयोग किया जाता है आपका भी उपयोग कर सकते हैं 210। यही वह है जिसे आप ग्रोवी की अंतर्निहित विधि कह सकते हैं।

अपने वर्ग में घोषित इस:

def propertyMissing(String name) { 
    if (name.contains(".")) { 
     def (String propertyname, String subproperty) = name.tokenize(".") 
     if (this.hasProperty(propertyname) && this."$propertyname".hasProperty(subproperty)) { 
      return this."$propertyname"."$subproperty" 
     } 
    } 
} 

फिर वांछित के रूप में अपने गुण का संदर्भ लें:

def properties = "property1.property2" 
assert someGroovyObject."$properties" == someValue 

यह स्वचालित रूप से पुनरावर्ती है, और आप स्पष्ट रूप से एक विधि कॉल करने की जरूरत नहीं है। यह केवल एक गेटर है, लेकिन आप एक सेटर बनाने के लिए पैरामीटर के साथ एक दूसरा संस्करण परिभाषित कर सकते हैं।

नकारात्मकता यह है कि, जहां तक ​​मैं कह सकता हूं, आप केवल propertyMissing के एक संस्करण को परिभाषित कर सकते हैं, इसलिए आपको यह तय करना होगा कि गतिशील पथ नेविगेशन क्या है जिसके लिए आप इसका उपयोग करना चाहते हैं।