2011-03-10 15 views
13

में क्लोजर परिभाषा/स्रोत मुद्रित करें कोई भी जो जानता है कि ग्रोवी में बंद होने का स्रोत कैसे प्रिंट करता है?ग्रोवी

उदाहरण के लिए, मैं इस बंद (a से आबद्ध)

def a = { it.twice() } 

मैं String "it.twice()" या "{it.twice()}"

है करना चाहते हैं

बस एक साधारण toString बिल्कुल काम नहीं करेगा:

a.toString(); //results in: [email protected] 
+0

यह शायद अपने हालात से मेल नहीं खाएगी पास हो shuld, लेकिन आप अन्य रास्ते जाने के लिए सक्षम हो सकता है। ग्रोवीशेल के बाद से।मूल्यांकन() एक स्ट्रिंग निष्पादित करता है (उचित var बाइंडिंग के साथ), अगर बंद करना केवल एक स्ट्रिंग था? –

उत्तर

24

संक्षिप्त उत्तर आप नहीं कर सकते हैं। लंबे जवाब है:
क्या आप के लिए कोड की जरूरत पर निर्भर करता है, तो आप शायद

// file: example1.groovy 
def a = { it.twice() } 
println a.metaClass.classNode.getDeclaredMethods("doCall")[0].code.text 
// prints: { return it.twice() } 

लेकिन
के साथ भाग मिल सकता है के रूप में

में विस्तार से बताया आप स्क्रिप्ट रनटाइम पर classpath में उपलब्ध के स्रोत कोड की आवश्यकता होगी

groovy.lang.MetaClass # getClassNode()
"MetaClass के लिए मूल एएसटी के लिए एक संदर्भ मिल गया तो यह उपलब्ध है क्रम
०१२३५१६४१०६१ पर मूल एएसटी या नल @return अगर यह नहीं किया जा सकता ,

और
पाठ चाल लौटे "वास्तव में एक ही कोड, बस एएसटी के प्रतिनिधित्व की तरह एक कोड प्रदान नहीं करता के रूप में किया जा सकता है

// file: example2.groovy 
def b = {p-> p.twice() * "p"} 
println b.metaClass.classNode.getDeclaredMethods("doCall")[0].code.text 
// prints: { return (p.twice() * p) } 

अभी भी इस स्क्रिप्ट में देखा है, यह उपयोगी यह है के रूप में अगर तुम सिर्फ शीघ्रता से अवलोकन

ले जाना चाहते हो सकता है और, अगर आप अपने हाथों पर बहुत अधिक समय है और आप अपने खुद के org.codehaus.groovy.ast.GroovyCodeVisitor लिख सकता है सुंदर मुद्रित करने के लिए यह

या, जैसे groovy.inspect.swingui.AstNodeToScriptVisitor

// file: example3.groovy 
def c = {w-> 
    [1,2,3].each { 
    println "$it" 
    (1..it).each {x-> 
     println 'this seems' << ' somewhat closer' << ''' to the 
     original''' << " $x" 
    } 
    } 
} 
def node = c.metaClass.classNode.getDeclaredMethods("doCall")[0].code 
def writer = new StringWriter() 
node.visit new groovy.inspect.swingui.AstNodeToScriptVisitor(writer) 
println writer 
// prints: return [1, 2, 3].each({ 
//  this.println("$it") 
//  return (1.. it).each({ java.lang.Object x -> 
//   return this.println('this seems' << ' somewhat closer' << ' to the \n  original' << " $x") 
//  }) 
// }) 

पहले से मौजूद किसी अब चोरी क्या करना है पता नहीं है।
अगर आप मूल, सटीक, runnable कोड चाहते हैं ... आप
मेरा मतलब, आप स्रोत लाइन जानकारी इस्तेमाल कर सकते हैं भाग्य से बाहर हैं, लेकिन पिछली बार मैं जाँच की, यह वास्तव में उन्हें सही हो रही है नहीं कर रहा था

// file: example1.groovy 
.... 
def code = a.metaClass.classNode.getDeclaredMethods("doCall")[0].code 
println "$code.lineNumber $code.columnNumber $code.lastLineNumber $code.lastColumnNumber" 
new File('example1.groovy').readLines() 
... etc etc you get the idea. 

लाइन नंबर कम से कम मूल कोड हालांकि

+0

मुझे समझ में नहीं आता कि क्लासपाथ एटी रूंटिम में 'स्क्रिप्ट किस प्रकार उपलब्ध है' का अर्थ है? यह अभी तक काम नहीं करता है (क्लास नोड 'शून्य' है), लेकिन मेरे पास सभी स्रोत उपलब्ध हैं। क्या मुझे ग्रोवी प्रोजेक्ट के क्लासपाथ में स्क्रिप्ट का स्थान जोड़ना है? – Julian

+1

@ जुलिएन का अर्थ है। ग्रोवी फ़ाइल क्लासपाथ में होनी चाहिए। getClassNode() मूल रूप से फ़ाइल लोड करेगा, और इसे प्रासंगिक अस्थ नोड को सहेजने के लिए एक विशेष हुक के साथ फिर से संकलित करेगा, और इसे – jpertino

+2

@jpertino लौटाएगा इस पर कोई विचार है कि आप Grails पर्यावरण में ऐसा कैसे करेंगे? मेरे पास एक Config.groovy फ़ाइल है जो एकीकरण परीक्षण के दौरान कक्षा पथ पर है लेकिन यह रन-ऐप के दौरान नहीं है। – asinesio

5

ग्रूवी में संभव नहीं है यही कारण है कि। यहां तक ​​कि जब एक groovy स्क्रिप्ट सीधे चलाया जाता है, इसे पहले संकलित किए बिना, स्क्रिप्ट को JVM बाइटकोड में परिवर्तित कर दिया जाता है। क्लोजर का अलग-अलग इलाज नहीं किया जाता है, वे नियमित तरीकों की तरह संकलित होते हैं। कोड चलाए जाने तक, स्रोत कोड अब और उपलब्ध नहीं है।