Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using `evaluate` function. Why it doesn't work?

Tags:

groovy

eval

This code:

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

results in exception:

FATAL: No signature of method: script1409644336796288198097.test() is applicable for argument types: () values: [] Possible solutions: use([Ljava.lang.Object;), getAt(java.lang.String), use(java.util.List, groovy.lang.Closure), use(java.lang.Class, groovy.lang.Closure), wait(), wait(long) groovy.lang.MissingMethodException: No signature of method: script1409644336796288198097.test() is applicable for argument types: () values: [] Possible solutions: use([Ljava.lang.Object;), getAt(java.lang.String), use(java.util.List, groovy.lang.Closure), use(java.lang.Class, groovy.lang.Closure), wait(), wait(long) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55) ...

What I'm doing wrong?

like image 298
user626528 Avatar asked Sep 02 '14 07:09

user626528


2 Answers

If a variable has an undeclared type, then it goes into the script binding. The binding is visible to all methods which means data is shared.

evaluate() is a helper method to allow the dynamic evaluation of groovy expressions using this scripts binding as the variable scope.

In a variable binding, you can declare a closure which accepts no argument and must be restricted to calls without arguments.

With all of that in mind, here is your script working as intended.

evaluate ("test = { -> println \"Test is successful!\" }")
test()
like image 121
Sam Gleske Avatar answered Sep 28 '22 17:09

Sam Gleske


That script evaluation results in null. You should either return something or execute the script and return the result.

An example returning a closure instead of defining a method:

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

And an example where the script executes the method itself:

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

If you cannot change the script code, you may parse a class from the script, create a new object, and then execute the test() method:

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"
like image 21
Will Avatar answered Sep 28 '22 17:09

Will