Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JShell access to variables defined outside of jshell instance

From inside jShell script, is it possible to access or register variables that are defined in code that's also creating JShell?

Currently there seems to be no mechanism to either access or register a variable to Shell instance, or return none string types from inside JShell (like objects or lambda etc.)

ex:


    import jdk.jshell.JShell;
    import jdk.jshell.JShellException;
    import jdk.jshell.SnippetEvent;

    import java.util.List;


    public class Main {

        public static void main(String[] args) throws JShellException {
            var localVar = 1;
            JShell shell = JShell.create();
            // How to register localVar variable with shell instance or access variables from scope
            List events = shell.eval("var x = localVar;");
            SnippetEvent event = events.get(0);
            System.out.println("Kind: " + event.snippet().kind() + ", Value: " + event.value());
        }

    }

like image 271
Developer Avatar asked Mar 01 '19 21:03

Developer


People also ask

Which of the following command is used to come out of JShell prompt?

Other important commands include /exit to leave JShell, /save to save your snippets, and /open to enter snippets from a file.

Which import statements are loaded into the JShell session by default?

Startup Scripts. Startup scripts contain snippets and commands that are loaded when a JShell session is started. The default startup script contains common import statements.

What JShell command should we use to exit the current JShell session?

To exit JShell, type /exit . I stuck in JShell for minutes, commands like exit , ctrl + c , end , q! , q , quit all failed, the correct syntax to quit or exit the JShell is /exit .


1 Answers

While you can't access local names like in your example, you can create a JShell instance that executes in the same JVM that created it. For this you would use the LocalExecutionControl. Using this execution control you could move localVar to a static field in your Main class and then access it from "inside" the JShell code with Main.localVar.

Unfortunately as the API is designed to support execution providers that could be in a different process or even a different machine, the return type is a string. If you are interested in a hack, the IJava jupyter kernel needed to an implementation of eval that returned an Object which ended up using an ExecutionControl implementation based on the DirectExecutionControl that stored the result of an eval call in a map and returned a unique id to reference that result. Then using the shell you would have to lookup the result from the id returned by eval (think of something like results.get(eval(sourceCode))). That implementation is on github in IJavaExecutionControl.java and IJavaExecutionControlProvider.java with a sample usage in CodeEvaluator.java#L72 if you are interested in taking any of it (MIT license).

like image 178
SpencerPark Avatar answered Oct 13 '22 03:10

SpencerPark