Reflection 如何使用反射获取具有最后一个值的所有Groovy变量
我希望在groovy脚本中转储所有变量并显示所有值 我想动态地做这件事,因为我想用try/catch来包围我所有的大型Groove。在catch部分,我想用stacktrace转储所有变量状态。代码应该是所有Groove的通用代码 问题是this.getBinding.getVariables没有返回正确的变量状态 我制作了一个小脚本来说明这种情况:Reflection 如何使用反射获取具有最后一个值的所有Groovy变量,reflection,groovy,Reflection,Groovy,我希望在groovy脚本中转储所有变量并显示所有值 我想动态地做这件事,因为我想用try/catch来包围我所有的大型Groove。在catch部分,我想用stacktrace转储所有变量状态。代码应该是所有Groove的通用代码 问题是this.getBinding.getVariables没有返回正确的变量状态 我制作了一个小脚本来说明这种情况: def test1 = 1; test1 = 2; int test2 = 1; test2 = 2; test3 = 1; test3 =
def test1 = 1;
test1 = 2;
int test2 = 1;
test2 = 2;
test3 = 1;
test3 = 2;
def errLog=new File("c:/temp/groovy_debug.txt");
errLog.append("--------------------------------------------------------" + "\n");
errLog.append(" Context ["+getBinding().getVariables()+" ] \n");
errLog.append("--------" + "\n") ;
执行死刑后,我得到了一个非常奇怪的结果
--------------------------------------------------------
Context [[[creationStackTrace= <not available>], test1:null, errLog:null, test2:null, test3:2] ]
--------
这意味着声明的变量总是报告为null或作为第一个赋值,但对于非类型化变量,它会得到最后一个值。
我想得到所有变量value=2的最后一种情况
有可能得到它们吗 Tim Yates'解释了为什么您在访问非全局变量时遇到困难。对于像您这样只有赋值和声明的简单情况,您可以使用访问者来收集结果,如下所示
import org.codehaus.groovy.ast.expr.*
import org.codehaus.groovy.ast.stmt.*
import org.codehaus.groovy.ast.*
import org.codehaus.groovy.control.*
import org.codehaus.groovy.classgen.*
import java.security.CodeSource
def scriptText = '''
def test1 = 1;
test1 = 2;
int test2 = 1;
test2 = 2;
test3 = 1;
test3 = 2;
'''
class VariableVisitor extends ClassCodeVisitorSupport {
def vars = [:]
void visitExpressionStatement(ExpressionStatement statement) {
if (statement.expression instanceof BinaryExpression)
vars.put(statement.expression.leftExpression.name, statement.expression.rightExpression.value)
super.visitExpressionStatement(statement)
}
void visitReturnStatement(ReturnStatement statement) {
if (statement.expression instanceof BinaryExpression)
vars.put(statement.expression.leftExpression.name, statement.expression.rightExpression.value)
super.visitReturnStatement(statement)
}
protected SourceUnit getSourceUnit() {
return source;
}
}
class CustomSourceOperation extends CompilationUnit.PrimaryClassNodeOperation {
CodeVisitorSupport visitor
void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
classNode.visitContents(visitor)
}
}
class MyClassLoader extends GroovyClassLoader {
CodeVisitorSupport visitor
protected CompilationUnit createCompilationUnit(CompilerConfiguration config, CodeSource source) {
CompilationUnit cu = super.createCompilationUnit(config, source)
cu.addPhaseOperation(new CustomSourceOperation(visitor: visitor), Phases.CLASS_GENERATION)
return cu
}
}
def visitor = new VariableVisitor()
def myCL = new MyClassLoader(visitor: visitor)
def script = myCL.parseClass(scriptText)
assert visitor.vars == ["test1":2, "test2":2, "test3":2]
然而,如果你的脚本有更复杂的东西,比如条件赋值,你需要更复杂的东西。您需要实际运行脚本并收集结果。我在临时文件中的结果不同:-----------------------------Context[\u outputTransforms:[groovy.ui.OutputTransforms$\u loadOutputTransforms_closure1@27a97cea,groovy.ui.OutputTransforms$\u loadOutputTransforms_closure2@5d4803d2,groovy.ui.OutputTransforms$\u loadOutputTransforms_closure3@7f10fc0a,groovy.ui.OutputTransforms$\u loadOutputTransforms_closure4@517b5471,groovy.ui.OutputTransforms$\u loadOutputTransforms_closure5@3dd93c98],uu0:null,uuo:[],参数:[],测试3:2]]----这是完整的代码,还是更大项目的一部分?长度的limtt我的结果来自Groovy控制台。你还记得吗,Groovy脚本是run-in脚本类的隐藏实现吗?这是完整的脚本,但它是在另一个软件中计算的。当我试图使用this.getClass.getMethods列出所有方法时,我看到了很多方法。t这些都是Java方式的方法,每个OfficeJAL groovy对象/类都有很多。如果我理解的话,你的问题是关于局部变量的???。看这里,我想得到所有变量:局部、全局、静态、是否定义