mattyb149 / clojure-jsr223

Automatically exported from code.google.com/p/clojure-jsr223
0 stars 0 forks source link

Variables (bindings) set during an eval() not accessible outside the SciprtEngine. #3

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. create a script engine
2. eval("(def x 10)")
3. engine.getBindings(...).get(x) == null

What is the expected output? What do you see instead?

The variables set during the evaluation of a script and not be stored in the 
binding set of the script engine and thus, these variables are isolated to the 
engine and can't be shared between engines. This is a violation of the 
ScriptEngine specification.

What version of the product are you using? On what operating system?

1.0

See http://mutant.tinkerpop.com for application space. 
   - note the behavior of Rhino JSR 223, Groovy, and Gremlin as references for binding behavior in JSR 223.

Please provide any additional information below.

Original issue reported on code.google.com by okrammarko on 5 Dec 2010 at 7:02

GoogleCodeExporter commented 8 years ago
I found a potentially easy solution (perhaps inefficient though).

At the end of ClojureScriptEngine.eval(Reader, ScriptContext), loop through the 
Var key/value pairs and set the key/values to the context bindings.

  *** NOTE: I saw Var in ClojureScriptEngine.java: Var.intern(USER_NS, Symbol.create(key), value);

Original comment by okrammarko on 5 Dec 2010 at 7:35

GoogleCodeExporter commented 8 years ago
Thanks for raising this issue. I was under the impression that bindings applied 
one way, from Java to the engine. I'll try to work on this as soon as I can.

Original comment by abm221...@gmail.com on 7 Dec 2010 at 9:23

GoogleCodeExporter commented 8 years ago

Original comment by abm221...@gmail.com on 7 Dec 2010 at 9:23

GoogleCodeExporter commented 8 years ago
I've got a preliminary fix. It gets all vars created in the user namespace. The 
user namespace contains mappings for all public declarations in clojure.core 
but we don't want those, that's why the code filters those out. What if you 
want bindings in other namespaces? I don't know that; will ask somebody related 
to JSR 223.

    private void collectBindings(Bindings bindings) {
        for (ISeq seq = USER_NS.getMappings().seq(); seq != null; seq = seq.next()) {
            IMapEntry e = (IMapEntry) seq.first();
            String k = e.getKey().toString();
            Object val = e.getValue();
            if (val.toString().startsWith("#'user/")) {
                if (val instanceof Var) {
                    val = ((Var) val).deref();
                }           
                bindings.put(k, val);
            }
        }
    }

Original comment by abm221...@gmail.com on 12 Jan 2011 at 4:54

GoogleCodeExporter commented 8 years ago
There's a new jar with an intended fix. See the new download. You should be 
able to get any bindings from the execution of scripts, qualified with the 
namespace.

Bindings should now be properly set and retrieved to and from the Clojure 
runtime. Bound names have the form: namespace/var, as in user/foo. Unqualified 
names default to the namespace 'user'.

Original comment by abm221...@gmail.com on 12 Jan 2011 at 11:23