Skip to content

Fix DoubleField failing with JInt #1398

Closed
wants to merge 4 commits into from

3 participants

@ultramiraculous

Right now, any JSON value without a decimal value will fail when you try to put it into a DoubleField. For example:

{ "value": 1234 } becomes JField( "value", JInt(1234) ), which in turn makes DoubleField very upset because it doesn't know what to do with JInt.

I added a case for JInt in DoubleField's setFromJValue and added an associated test case.

In a separate commit I did the opposite for LongField/IntField so they can take JDoubles.

@eltimn

This is already imported above.

I completely wan't paying attention to what IntelliJ was doing to the imports. I can get that cleaned up.

@eltimn

The json package now has a nice package object, so just importing json._ works best.

@eltimn

This is already imported above.

@eltimn

Can toInt throw an Exception? If so, I'd wrap this in a tryo: setBox(tryo(d.toInt))

toInt/toLong/toDouble don't appear to throw any exceptions. In this case, we'd be calling .doubleValue on BigInteger (via Scala's BigInt.toDouble) and java Double's .intValue/.longValue (via Scala double). There's no exceptions, just potentially lost precision.

Lift Web Framework member

Are you saying it will not through an exception because JDouble already does some filtering?

Because calling "name".toInt does through an exception:

scala> "22".toInt
res0: Int = 22

scala> "22d".toInt
java.lang.NumberFormatException: For input string: "22d"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:492)
    at java.lang.Integer.parseInt(Integer.java:527)
    at scala.collection.immutable.StringLike$class.toInt(StringLike.scala:229)
    at scala.collection.immutable.StringOps.toInt(StringOps.scala:31)
    at .<init>(<console>:8)
    at .<clinit>(<console>)
    at .<init>(<console>:7)
    at .<clinit>(<console>)
    at $print(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:731)
    at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:980)
    at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:570)
    at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:601)
    at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:565)
    at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:745)
    at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:790)
    at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:702)
    at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:566)
    at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:573)
    at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:576)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:867)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:822)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:822)
    at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
    at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:822)
    at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:889)
    at xsbt.ConsoleInterface.run(ConsoleInterface.scala:57)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at sbt.compiler.AnalyzingCompiler.call(AnalyzingCompiler.scala:73)
    at sbt.compiler.AnalyzingCompiler.console(AnalyzingCompiler.scala:64)
    at sbt.Console.console0$1(Console.scala:23)
    at sbt.Console$$anonfun$apply$2$$anonfun$apply$1.apply$mcV$sp(Console.scala:24)
    at sbt.TrapExit$.executeMain$1(TrapExit.scala:33)
    at sbt.TrapExit$$anon$1.run(TrapExit.scala:42)

Yeah, basically. By the time you get to this match statement, you have a processed JValue from the AST, so if you get a JDouble/JInt, you're assured that you have an actual number that was parsed out.

DecimalField. for instance, does need a tryo because it's assuming it's getting a number as a string with some context attached, so it gets parsed at the field level, not the AST level.

@eltimn

All of my comments from the previous file apply to this one as well.

@fmpwizard
Lift Web Framework member

Rebased to master

@fmpwizard fmpwizard closed this Jan 24, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.