2011-10-25 8 views
6

मैं ग्रोवी में एक अज्ञात आंतरिक कक्षा को कैसे परिभाषित करूं? मैंने संदर्भ देखा कि उन्हें ग्रोवी 1.7 में समर्थित होना चाहिए और मैं 1.8 का उपयोग कर रहा हूं।मुझे ग्रोवी में अज्ञात आंतरिक कक्षा की तरह कुछ कैसे मिलता है?

thread = process.consumeProcessOutput(
    new Appendable() { 
    Appendable append(char c) { 
     app1.append(c) 
     app2.append(c) 
     return this 
    } 

    Appendable append(CharSequence csq) { 
     app1.append(csq) 
     app2.append(csq) 
     return this 
    } 

    Appendable append(CharSequence csq, int start, int end) { 
     app1.append(csq, start, end) 
     app2.append(csq, start, end) 
     return this 
    } 
    }) 

मैं इस कोड के साथ एक अपवाद प्राप्त करें:

Caught: groovy.lang.MissingMethodException: No signature of method: java.lang.UNIXProcess.consumeProcessOutput() is applicable for argument types: (MyClass$1) values: [[email protected]] 
+0

अच्छी तरह से किस प्रकार का उपभोग करता हैप्रोसेऑटपुट की आवश्यकता होती है? क्या यह स्वीकार्य इंटरफ़ेस है? –

+0

शब्द है कि आपके सवाल का वर्णन करता है एक "बंद" मुझे लगता है ... – djangofan

+0

कहा जाता है यह स्वीकार करता है Appendable और OutputStream – dromodel

उत्तर

0

इस हाल ही में एक इंडिगो में काम करता है:

List l=new LinkedList() { 
      { 
       add(new Integer(1)); 
       add(new Integer(2)); 
      } 
     }; 
println l 
6

यह एक मुश्किल मामला है के बाद से तरीकों वस्तु ही वापस लौटाना होगा Appendable के रूप में, और एक अधिभारित विधि नाम है जो इंटरफ़ेस कास्टिंग करने के लिए ग्रोवी मानचित्र के साथ अच्छी तरह से काम नहीं करता है। सबसे सरल, स्पष्ट तरीका शायद एक अज्ञात आंतरिक वर्ग का उपयोग करना है, जैसा कि आप जावा में करेंगे।

def testAppendable(Appendable appendable) { 
    println "appendable = $appendable" 
    appendable.append('a' as char). 
       append('b' as char). 
       append('c' as char) 
} 

testAppendable(new Appendable() { 
    Appendable append(char c) { 
     println "got $c" 
     this 
    } 
    Appendable append(CharSequence csq) { 
     this 
    } 
    Appendable append(CharSequence csq, int start, int end) { 
     this 
    } 
    String toString() { "inner class appendable" } 
}); 

एक अन्य विकल्प बंद के साथ एक Expando उपयोग करने के लिए किया जाएगा: यह ग्रूवी (1.7 या नए मुझे लगता है कि) के एक यथोचित वर्तमान संस्करण की आवश्यकता है। यह थोड़ा अजीब है क्योंकि प्रति विधि नाम केवल एक कार्यान्वयन कन्स्ट्रक्टर में शुरू किया जा सकता है। ध्यान दें कि छोड़े गए किसी भी इंटरफ़ेस विधियों को एक डिफ़ॉल्ट कार्यान्वयन दिया जाता है जो अपवाद फेंकता है।

testAppendable(new Expando(
    append: { char c -> 
     println "got $c" 
     delegate as Appendable 
    }, 
    toString: { -> 
     "expando appendable" 
    } 
) as Appendable) 

संपादित करें: आपके उदाहरण के बारे में, मुझे नहीं लगता कि यह क्यों विफल होगा। मेरा परीक्षण लगभग समान है और बिना किसी समस्या के काम करता है। process.consumeProcessOutput का हस्ताक्षर कैसा दिखता है? साथ ही, आप javap MyClass$1 चलाकर MyClass$1 लागू कर सकते हैं Appendable लागू कर सकते हैं।

+0

+1 जोड़ा गया [एक मानचित्र के साथ ऐसा करने का संभावित समाधान] (http://stackoverflow.com/questions/7895545/how-do-i-get-something-like-an-anonymous-inner-class-in- groovy/7900626 # 7900626), लेकिन अगर कोई विकल्प दिया गया तो मैं आपका मार्ग जाऊंगा ;-) –

3

@ataylor's solution above के अतिरिक्त के रूप में, यह Map as Appendable संकेतन का उपयोग करने के लिए संभव है, लेकिन यह एक फ़ज का एक सा है:

को देखते हुए परीक्षण समारोह:

def testAppendable(Appendable appendable) { 
    println "appendable = $appendable" 
    appendable.append('a' as char). 
       append("GROOVY",1,2). 
       append("TIM") 
} 

हम अपने Appendable निर्माण कर सकते हैं thusly:

def app 
app = [ append:{ a, b=null, c=null -> 
      if(a.grep(CharSequence)) a = a[ (b?:0)..<(c?:a.length()) ] 
      println "Got $a" 
      app 
     } ] as Appendable 
फिर

,

क्रियान्वित बाहर

appendable = {[email protected]} 
Got a 
Got R 
Got TIM 

अपेक्षा के अनुरूप ...

स्थिति पर निर्भर करता

testAppendable(app) 

प्रिंट्स, मैं हालांकि यह इस तरह से कर रही है से बचने के लिए, के रूप में गुमनाम वर्ग मार्ग में कहीं अधिक पठनीय है करते हैं; -)

1

आपकी अनाम कक्षा ठीक होनी चाहिए। के बाद से अपने सभी तरीकों सिर्फ Appendable के दो अन्य मामलों को सौंप आप भी इस तरह इसे लागू कर सकते हैं:

final tee 
tee = { 
    final... args 
-> 
    app1.append(*args) 
    app2.append(*args) 

    return tee 
} as Appendable 

* ऑपरेटर ग्रूवी args अपने तर्कों के रूप में की सामग्री के साथ #append कॉल करने के लिए कारण बनता है।

MissingMethodException आपको मिल रहा है क्योंकि #consumeProcessOutput दो तर्क लेता है- एक STDOUT के लिए और एक एसटीडीईआरआर के लिए।यह प्रक्रिया को अवरुद्ध करने से रोकने के लिए केवल आउटपुट से पर्याप्त पढ़ता है, इसलिए शायद यह नहीं है कि आप यहां क्या चाहते हैं। इसके बजाय #waitForProcessOutput आज़माएं।

final app1 = new StringBuilder() 
final app2 = new StringBuilder() 

final tee 
tee = { 
    final... args 
-> 
    app1.append(*args) 
    app2.append(*args) 

    return tee 
} as Appendable 

final cmd = 'ps a' 
final p = cmd.execute() 

p.waitForProcessOutput tee, tee 

println '*' * 80 
println app1 
println '*' * 80 
println app2 
संबंधित मुद्दे