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

查看:20
本文介绍了在 Groovy 中打印闭包定义/源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁知道如何在 Groovy 中打印闭包的来源?

Anyone who knows how the print the source of a closure in Groovy?

例如,我有这个闭包(绑定到 a)

For example, I have this closure (binded to a)

def a = { it.twice() } 

我想要Stringit.twice()"或{ it.twice() }"

I would like to have the String "it.twice()" or "{ it.twice() }"

只是一个简单的toString当然是行不通的:

Just a simple toString ofcourse won't work:

a.toString(); //results in: Script1$_run_closure1_closure4_closure6@12f1bf0

推荐答案

简短的回答是你不能.长答案是:
根据您需要代码的用途,您也许可以逃脱

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
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 如果它不能返回"

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"


text 技巧并没有真正返回相同的代码,只是一个类似于 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

或者,只是窃取一个现有的,比如 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 
      original' << " $x")
//     })
// })

现在.
如果您想要原始、准确、可运行的代码……那您就走运了
我的意思是,你可以使用源代码行信息,但上次我检查时,它并没有真正让它们正确

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天全站免登陆