Rhino: Java numbers don't behave like Javascript numbers -
i have instance of java class accessible in javascript program
public class contentprovider { public object c(int n) { switch (n) { case 1: return 1.1; case 2: return 2.2; case 3: return 3.3; case 4: return "4"; case 5: return new java.util.date(); } return null; } }
this code inside main():
scriptenginemanager mgr = new scriptenginemanager(); scriptengine engine = mgr.getenginebyname("javascript"); engine.put("ctx", new contentprovider()); res = engine.eval("ctx.c(1)"); system.out.printf("rhino:> %s (%s)%n" , res , res != null ? res.getclass().getname() : null );
the simple expression ctx.c(1)
prints:
rhino:> 1.1 (java.lang.double)
now here happens ctx.c(1) + ctx.c(2)
:
rhino:> 1.12.2 (java.lang.string)
and (ctx.c(1) + ctx.c(2)) * ctx.c(3)
:
rhino:> nan (java.lang.double)
rhino performing string concatenation instead of number arithmetics! following program works expected instead:
engine.put("a", 1.1); engine.put("b", 2.2); engine.put("c", 3.3); res = engine.eval("(a + b) * c");
outputs:
rhino:> 10,89 (java.lang.double)
this strange feature of rhino: java number
set engine.put("one", new double(1))
works expected, while result of java method depends on return type declared method itself, read reflection api:
- if it's primitive,
double
, it's converted javascript number - otherwise it's handled other host objects ,
+
means concatenation, eitherobject
in sampledouble
you can configure behavior wrapfactory.setjavaprimitivewrap(false)
on wrapfactory
in current context
. way rhino code can kept in bootstrap lines of program , doesn't clutter contentprovider
(which guess sort of configuration proxy)
from live javadoc of wrapfactory.isjavaprimitivewrap()
by default method returns true indicate instances of string, number, boolean , character should wrapped other java object , scripts can access java method available in these objects
so can set flag false
indicate java number
's should converted javascript numbers. takes 2 lines of code
context ctx = context.enter(); ctx.getwrapfactory().setjavaprimitivewrap(false);
here the gist full code used test
Comments
Post a Comment