4

with jshell, is there a way to create variables in the scope of the interpreter? I have something like

Map<String,Object> vars = loadVarsFromSomething();

and I would like to be able to do something like

for ( Map.Entry<String,Object> key : vars )
{
  scope.put( key.getKey(), key.getValue() );
}

Is that possible?

Note here that the "scope" I am referring to is the actual scope of the Shell object that is being used by jshell interpreter.. I need to get a reference to the shell that the code is being invoked from so that I can create variables that look as if they were assigned by the user/caller ..

Naman
  • 27,789
  • 26
  • 218
  • 353
crow
  • 1
  • 1
  • 10
  • 1
    Yes, you can. What's the problem? – Russiancold Oct 17 '17 at 17:54
  • how do i get a reference to scope? can i get a reference to the Shell object thru which it was invoked or something? – crow Oct 18 '17 at 02:31
  • 2
    What do you mean with 'reference of the scope'? JShell creates a remote process (JVM) for execution. There is no 'JShell scope', as your code is executed like it would without JShell. The reason why 'ignorant people downvoted' your question, is because it is unclear what exactly you're asking.. JShell is not a hashmap, as your example seems to imply. – NickL Oct 21 '17 at 22:26
  • If what you mean by 'JShell scope' is that a variable must be available upon startup of any session, it is possible. Overwrite the default script by issuing command: `--startup file` as explained here: https://docs.oracle.com/javase/9/tools/jshell.htm#JSWOR-GUID-C337353B-074A-431C-993F-60C226163F00 – Thibstars Oct 22 '17 at 10:14
  • @nickl that's what I'm asking. if there's a way for the code to get reference to the Shell its being interpreted in... in matlab when you load a .mat file it creates variables based on the names of the arrays in the file... i want to implement the same functionality – crow Oct 22 '17 at 17:30

2 Answers2

6

To load variables from an input file you can make use of the Jshell script itself.

Assuming the Jshell script named some.jsh needs to supply two variables such that one of them is a String and another is a primitive integer.

// Random stuff initially
{
  System.out.println("One Jshell Script");
}
// Variables to be supplied when jshell loads.
int x = 10;
String y = "Cool";

On executing the above script using:

jshell some.jsh 

You can thereafter access these variables with their identifiers as follows:-

enter image description here

Undoubtedly, you can make use of more complex data structure(in your case Map<String,Object> vars) as well as you store information in the script.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • That would be a terrible hack.. the variables returning from my MatFile implementation are memory-mapped to possibly gigabytes of direct buffer storage.. to write out a garganguatuan .jsh file just so it could be sourced would be such a kludge as to be basically unthinkable – crow Oct 23 '17 at 05:34
  • 2
    @crow In that case, could you improve the details in question and explain what precisely is your use case and how are the variables mapped and would be used? Also, please do add what hints you to believe that Jshell could be used for this task. – Naman Oct 23 '17 at 06:00
  • 2
    @crow This answer is fine for the question as asked. You are moving the goal-posts by stating a new requirement in the comments re: gigabytes of buffer storage. You should definitely update the question to accurately express the problem/goal. – Michael Easter Oct 24 '17 at 02:12
1

No, I don't believe it's possible to do what you are asking for. I'm not sure exactly what your use case is, but perhaps you can use the following snippet for ideas:

jshell> /vars 
|    HashMap<String, Object> vars = {bar=2, foo=1}

jshell> try (PrintStream out = new PrintStream(new FileOutputStream("tmp.jsh"))) {
...>     vars.forEach((k, v) -> out.printf("Object %s = vars.get(\"%s\")\n", k, k));
...> }

jshell> /open tmp.jsh

jshell> /vars 
|    HashMap<String, Object> vars = {bar=2, foo=1} 
|    Object bar = 2 
|    Object foo = 1

jshell>
Per Huss
  • 4,755
  • 12
  • 29
  • it would easily be possible using ThreadLocalStorage for some code to know if it was being executed in jshell. string parsing to accomplish this is unacceptable. its bad code – crow Oct 26 '17 at 14:28
  • @crow You clearly have some understanding of what you believe JShell can and cannot do, but you are not communicating what you have tried to do or intend to do. Your example is too generic, and others have pointed out that it does not clearly express your problem/goal. What does ThreadLocalStorage have to do with this? Do you think code is executed in the same Thread as JShell? Code is not executed _in_ JShell, it is executed _by_ JShell in a seperate JVM. – NickL Oct 26 '17 at 15:08
  • Well fooey... maybe I'll have to do some reflection API or bytecode magic to construct a class with the fields set dynamically.. in matlab you can do this: matlab> load blah.mat # contains X malab> X 0.1 0.2 0.3 ... – crow Oct 26 '17 at 18:04
  • @crow ThreadLocalStorage (ThreadLocal?), reflection or bytecode magic? Are you just namedropping or do you actually have a plan for _how_ to make it happen? – Per Huss Oct 26 '17 at 21:54
  • well I could use some low level API to construct an object having public fields equal to the names of the variables in the .mat file and return that.. but its still not the same.. might as well keep the return as hashmap... I thought jshell might be closer to invoking java.. that stinks.. maybe I'll have to make a fork of jshell or something – crow Oct 27 '17 at 00:09