在Groovy中打印闭包定义/源 [英] print the closure definition/source in Groovy

查看:210
本文介绍了在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆