Open sdyura opened 11 months ago
There are two issues in your code.
1) The local variable output
is only valid in the scope of the if
and will not be exported to the engine caller.
2) The return
statement does not work the same way in jshell
as it does in java
. It will not end the execution of the script.
You can solve both issues by writing your snippet like this:
private static void runJShellBindingExample2() {
try {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("jshell");
String script = "" +
"var output = \"\";" +
"if (inputA != null && inputB != null) {" +
" System.out.println(\"Input A: \" + inputA);" +
" System.out.println(\"Input B: \" + inputB);" +
" output = inputA + \" \" + inputB;" +
" System.out.println(\"OUTPUT HAS BEEN SET: \" + output);" +
"}" +
"output";
engine.put("inputA", "hello");
engine.put("inputB", "world");
Object result = engine.eval(script);
System.out.println("runJShellBindingExample2 Result: " + result);
Object output = engine.get("output");
System.out.println("Output Variable: " + output);
} catch (ScriptException e) {
e.printStackTrace();
}
}
This will give the following output in the console:
Input A: hello
Input B: world
OUTPUT HAS BEEN SET: hello world
runJShellBindingExample2 Result: hello world
Output Variable: hello world
sorry about my including the printout of the "output" variable, thats was just copied over from another example and you can ignore it
the issue is the return statement, if i call return with one value, i do not expect the 2nd return to also get called in java good practice i have always been told to return early when i have the result i need and returns not working makes this impossible.
I am trying to add scripting in a familiar language to my app, but your second point:
The return statement does not work the same way in jshellas it does in java. It will not end the execution of the script.
is very confusing, everything else works like java, but return does not end execution? this seems to just be asking for things to go wrong and mistakes to slip in.
why can this not be fixed so that return DOES end the script. what would be the harm in that?
it seems the first return statement literally does nothing, thats not expected.
even if for whatever reason you want to run the script AFTER the first return, it would make much more sense for:
Object result = engine.eval(script);
to give me the value of the FIRST return statement, not the last.
so if the code does execute over several return statements, only the first one is kept, and any subsequent returns can be ignored. so that the eval method returns the result of the First return that was called.
Maybe I could not explain it clearly.
In JShell the return
statement is only defined to work inside of functions, not outside of functions.
For example the following script:
int a = 2;
int b = 2;
System.out.println("Before if statement");
if (a > b) {
System.out.println("a is larger than b");
return a;
} else {
System.out.println("a is smaller or equal than b");
return b;
}
System.out.println("After if statement");
will show warnings on the return statements (at least in the IntelliJ IDEA) and when executeed will produce the following output:
Defined field int a = 2
Defined field int b = 2
System.out.println("Before if statement")
Before if statement
if (a > b) {
System.out.println("a is larger than b");
return a;
} else {
System.out.println("a is smaller or equal than b");
return b;
}
a is smaller or equal than b
System.out.println("After if statement")
After if statement
Please note that the println("After if statement") is being executed although there where return statements in the if.
This is a feature of the JShell and has nothing to do with the JSR233 implementation of jshell-scriptengine
.
here is some code:
when i run it i get this back:
even though i would expect to get:
(tested on version 1.1.0)