在Groovy中打印闭包定义/源 [英] print the closure definition/source in Groovy
问题描述
任何人知道如何打印Groovy中的闭包的来源?
Anyone who knows how the print the source of a closure in Groovy?
例如,我有这个闭包(绑定到 / code>)
For example, I have this closure (binded to a
)
def a = { it.twice() }
我想拥有 String
it.twice it.twice()}
I would like to have the String
"it.twice()" or "{ it.twice() }"
只是一个简单的 toString
ofcourse将无法工作:
Just a simple toString
ofcourse won't work:
a.toString(); //results in: Script1$_run_closure1_closure4_closure6@12f1bf0
推荐答案
short答案是你不能。长回答是:
根据你需要的代码,你也许可以用
short answer is you can't. long answer is:
depending on what you need the code for, you could perhaps get away with
// file: example1.groovy
def a = { it.twice() }
println a.metaClass.classNode.getDeclaredMethods("doCall")[0].code.text
// prints: { return it.twice() }
BUT
需要在类路径中提供的脚本的源代码AT RUNTIME,如
BUT
you will need the source code of the script available in the classpath AT RUNTIME as explained in
groovy.lang.MetaClass#getClassNode
如果
在运行时可用,获取对MetaClass的原始
AST的引用
@return
原始AST或null如果不能be
返回
groovy.lang.MetaClass#getClassNode()
"Obtains a reference to the original AST for the MetaClass if it is available at runtime
@return The original AST or null if it cannot be returned"
AND
真正返回相同的代码,只是像AST的代码一样,可以在这个脚本中看到
AND
the text trick does not really return the same code, just a code like representation of the AST, as can be seen in this script
// file: example2.groovy
def b = {p-> p.twice() * "p"}
println b.metaClass.classNode.getDeclaredMethods("doCall")[0].code.text
// prints: { return (p.twice() * p) }
仍然可能是有用的,因为它是如果你只是想快速看看
still, it might be useful as it is if you just want to take a quick look
和,如果你有太多的时间在你的手上,不知道该怎么做,你可以写自己的 org.codehaus。 groovy.ast.GroovyCodeVisitor
到漂亮的打印
AND, if you have too much time on your hands and don't know what to do you could write your own org.codehaus.groovy.ast.GroovyCodeVisitor
to pretty print it
OR,只是窃取一个现有的像 groovy.inspect.swingui .AstNodeToScriptVisitor
OR, just steal an existing one like 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")
// })
// })
现在。
如果您想要原始精确,可运行的代码...你没有运气
i意思是,你可以使用源代码信息,但上次我检查,它不是真正让他们正确
now.
if you want the original, exact, runnable code ... you are out of luck
i mean, you could use the source line information, but last time i checked, it wasn't really getting them right
// 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.
行号必须至少接近原始代码。
line numbers shuld be at least near the original code though
这篇关于在Groovy中打印闭包定义/源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!