Reflection 如何使用反射获取具有最后一个值的所有Groovy变量

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 =

我希望在groovy脚本中转储所有变量并显示所有值

我想动态地做这件事,因为我想用try/catch来包围我所有的大型Groove。在catch部分,我想用stacktrace转储所有变量状态。代码应该是所有Groove的通用代码

问题是this.getBinding.getVariables没有返回正确的变量状态

我制作了一个小脚本来说明这种情况:

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对象/类都有很多。如果我理解的话,你的问题是关于局部变量的???。看这里,我想得到所有变量:局部、全局、静态、是否定义