使用`evaluate`功能。为什么它不起作用?

时间:2014-09-02 07:59:24

标签: groovy eval

此代码:

evaluate ("def test() { println \"Test is successful!\" }")
test()

导致异常:

  

致命:没有方法签名:script1409644336796288198097.test()适用于参数类型:()值:[]   可能的解决方案:使用([Ljava.lang.Object;),getAt(java.lang.String),使用(java.util.List,groovy.lang.Closure),使用(java.lang.Class,groovy.lang。关闭),wait(),等待(长)   groovy.lang.MissingMethodException:没有方法签名:script1409644336796288198097.test()适用于参数类型:()值:[]   可能的解决方案:使用([Ljava.lang.Object;),getAt(java.lang.String),使用(java.util.List,groovy.lang.Closure),使用(java.lang.Class,groovy.lang。关闭),wait(),等待(长)       在org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)   ...

我做错了什么?

4 个答案:

答案 0 :(得分:12)

该脚本评估结果为null。您应该返回一些内容或执行脚本并返回结果。

返回闭包而不是定义方法的示例:

test = evaluate ('return { "Test is successful!" }')
assert test() == "Test is successful!"

脚本执行方法本身的示例:

result = evaluate 'def test() { "eval test" }; return test()'
assert result == "eval test"

如果您无法更改脚本代码,可以parse a class from the script创建一个新对象,然后执行test()方法:

def parent = getClass().getClassLoader()
def loader = new GroovyClassLoader(parent)
def clazz = loader.parseClass('def test() { "new class definition" }');

obj = clazz.newInstance()
assert obj.test() == "new class definition"

答案 1 :(得分:0)

您可以使用ExpandoMetaClass将动态闭包添加到您自己的类中。您需要事先解析字符串,将其拆分为函数名,参数和代码。

methodName = "test"
methodArgs = []
methodCode = """println "Hello World!" """

this.metaClass."$methodName"{ code, args ->
  evaluate(code)
}

然后你可以这样做:

"$methodName"(code, arguments)

test(code, arguments)

获取输出Hello World!

您可以在此处阅读有关ExpandoMetaClass的更多信息http://groovy.codehaus.org/ExpandoMetaClass

答案 2 :(得分:0)

如果变量具有未声明的类型,则为it goes into the script binding。绑定对所有方法都是可见的,这意味着共享数据。

evaluate() is a helper method允许使用this脚本绑定作为变量范围来动态评估groovy表达式。

在变量绑定中,您可以declare a closure不接受任何参数,并且必须限制为不带参数的调用。

考虑到所有这些,这里的脚本按预期工作。

evaluate ("test = { -> println \"Test is successful!\" }")
test()

答案 3 :(得分:0)

除了所有其他答案之外,如果您不想更改代码的结构,只需在groovy-string的末尾使用return this

lib = evaluate ("def test() { println \"Test is successful!\" }; return this")
lib.test()