Posted by
dscho on
Mar 17, 2013; 3:00pm
URL: http://imagej.273.s1.nabble.com/isOpen-path-tp5002210p5002234.html
Dear Wayne,
On Sat, 16 Mar 2013, Rasband, Wayne (NIH/NIMH) [E] wrote:
> Hi Johannes,
>
> On Mar 16, 2013, at 2:57 PM, Johannes Schindelin wrote:
>
> > Hi Wayne,
> >
> > On Sat, 16 Mar 2013, Johannes Schindelin wrote:
> >
> >> function getOpenedPaths() {
> >> // we need to use a system property since returning values from
> >> // eval("script", script) is broken in ImageJ 1.47m
> >> unused = call("java.lang.System.setProperty", "hopefully.unused", "");
> >> [...]
> >
> > The problem is that even after the attempt to imitate the Fiji
> > scripting framework by introducing the PlugInInterpreter class,
> > Macro_Runner#runJavaScript(String, String) still returns always null,
> > never an evaluated value:
> >
> >
https://github.com/fiji/imagej1/blob/master/ij/plugin/Macro_Runner.java#L233> >
> > sets 's', but a couple of lines later, it still just returns null in
> > every case.
> >
> > Can you please fix that bug?
>
> The PlugInInterpreter class is currently not used to run JavaScript
> scrips and Macro_Runner.runJavaScript() has always returned null.
That matches exactly what I reported ;-)
> How would you propose returning a value from a JavaScript script? We
> can't use the return statement because it is only allowed in functions.
> The only thing I can think of is assigning the return value to a
> variable and then retrieving the value of that variable.
The trick is not to use a 'return' statement (because -- as you pointed
out correctly -- the top-level script is not a function), but an
unassigned expression:
eval("script", "1;");
This patch (which you can conveniently get into your working directory by
calling "git pull git://github.com/dscho/imagej1 fix-js-return") makes
that work:
-- snip --
diff --git a/ij/plugin/Macro_Runner.java b/ij/plugin/Macro_Runner.java
index 257ac6d..254f7d6 100644
--- a/ij/plugin/Macro_Runner.java
+++ b/ij/plugin/Macro_Runner.java
@@ -236,7 +236,7 @@ private static String runScript(Object plugin, String script, String arg) {
IJ.runPlugIn("Jython", script);
}
}
- return null;
+ return "" + js;
}
/** Runs a BeanShell script the on current thread. Uses the plugin at
diff --git a/plugins/JavaScriptEvaluator.source b/plugins/JavaScriptEvaluator.source
index f72064a..37341c5 100644
--- a/plugins/JavaScriptEvaluator.source
+++ b/plugins/JavaScriptEvaluator.source
@@ -13,6 +13,7 @@ import javax.script.*;
public class JavaScriptEvaluator implements PlugIn, Runnable {
Thread thread;
String script;
+ private Object result;
// run script in separate thread
public void run(String script) {
@@ -33,12 +34,13 @@ public class JavaScriptEvaluator implements PlugIn, Runnable {
}
public void run() {
+ result = null;
try {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine engine = scriptEngineManager.getEngineByName("ECMAScript");
if (engine == null)
{IJ.error("Could not find JavaScript engine"); return;}
- engine.eval(script);
+ result = engine.eval(script);
} catch(Throwable e) {
String msg = e.getMessage();
if (msg.startsWith("sun.org.mozilla.javascript.internal.EcmaError: "))
@@ -50,4 +52,8 @@ public class JavaScriptEvaluator implements PlugIn, Runnable {
}
}
+ @Override
+ public String toString() {
+ return "" + result;
+ }
}
-- snap --
> Passing of arguments to JavaScript scripts also needs to be fixed. How
> would you propose doing that?
I do not think that there is a lot to fix. Last time I tried (with Fiji's
scripting framework, which I would have been happy to contribute to ImageJ
1.x), using GenericDialog instances (and calling the scripts via run(...,
args);) worked just fine.
If you want a solution that is safe to execute in headless mode, and that
allows easily for adding new interpreters without having to reference
those interpreters in ImageJ 1.x' core explicitly, I am afraid that you
would have to either use ImageJ2's scripting framework or replicate the
complete functionality thereof. If you want to benefit from my work, I
would be delighted to discuss how to adjust it to be able to use it from
vanilla ImageJ 1.x.
Ciao,
Johannes
--
ImageJ mailing list:
http://imagej.nih.gov/ij/list.html