2011-03-10 26 views
13

Groovy'de bir kapağın kaynağını nasıl yazdırdığını bilen var mı?Groovy'de kapama tanımını/kaynağını yazdır

Örneğin, (a binded) bu kapak

def a = { it.twice() } 

I String "it.twice()" ya da "{it.twice()}"

istiyorum sahip

Sadece basit toString tabii çalışmaz: groovy mümkün değildir

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

olsa orijinal kod yanında olmak shuld, ancak diğer tarafa gitmek mümkün olabilir. GroovyShell'den beri.assessment() bir String (uygun var bindings ile) yürütür, eğer kapanış basitçe bir string ise? –

cevap

24

Kısa cevap yapamazsınız. Uzun cevap:
için kod gerekenler bağlı olarak, belki

açıklandığı gibi çalışma zamanında sınıf yolunda mevcut senaryonun kaynak kod gerekir

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

AMA
kurtulabilirsin zamanında
mevcut ise

groovy.lang.MetaClass # getClassNode()
"metaclass için orijinal AST başvuru edinir olamaz eğer olabildiğince orijinal AST veya boş @return , gerçekten aynı kodu, AST temsil etmek gibi bir kodu vermemesi "

VE
metin trick döndü

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

hala bu komut görülen, sadece hızlı bir bakış

almak istiyorsanız olduğu gibi yararlı olabilir VE olabilir eğer ellerinize çok fazla zaman varsa ve oldukça o

YA, sadece şimdi 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") 
//  }) 
// }) 

gibi varolan bir çalmak yazdırmak için org.codehaus.groovy.ast.GroovyCodeVisitor kendi yazabilirsiniz ne yapacağını bilmiyorum. Eğer orijinal, tam, katedilebilen kod isterseniz
... Eğer
demek, kaynak çizgisi bilgisini kullanabilir şans bulunmaktadır, ama son baktığımda gerçekten doğru

bunları elde değildi
// 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. 

satır numaraları en az Bu muhtemelen durum uymayacak

+0

'RUNTIME AT sınıf yolunda kullanılabilir' komutunun tam olarak ne anlama geldiğini anlamıyorum. Henüz çalışmıyor (ClassNode, 'null'), ancak mevcut tüm kaynaklara sahibim. Senaryo konumunu Groovy projesinin sınıf yoluna eklemek zorunda mıyım? – Julian

+1

@Julian, .groovy dosyasının sınıf yolunda olması gerektiği anlamına gelir. getClassNode() temel olarak dosyayı yükler ve ilgili ast düğümünü kaydetmek için özel bir kanca ile tekrar derler ve geri döndürür – jpertino

+2

@jpertino Bunu Grails ortamında nasıl yapacağınıza dair herhangi bir düşünce var mı? Entegrasyon testleri sırasında sınıf yolunda bulunan bir Config.groovy dosyası var, ancak çalışma-uygulama sırasında değil. – asinesio

5

. Bir groovy betiği doğrudan çalıştırılsa bile, ilk önce derlemeden, betik JVM bayt koduna dönüştürülür. Kapanışlar farklı muamele görmez, düzenli yöntemler gibi derlenir. Kod çalıştırıldığında, kaynak kodu artık kullanılamaz.