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, eitherobjectin 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