stack overflow - scala implicit causes StackOverflowError -
how implicit val cause stackoverflowerror?
(pared down original code, still cause error)
object complicit { // class name, default, , conversion function implicit val case class cc[a](name: string, defaultvalue: a)(implicit val convert: string => a) { def getfrom(s: string): a= try { convert(s) } catch { case t: throwable => println("error: %s".format(t)) // see stackoverflowexception defaultvalue } } // works fine object works { val cc1= cc("first", 0.1)(_.todouble) } // causes java.lang.stackoverflowerror due implicit object fails { // !!! stackoverflowerror here implicit val stringtodouble: string => double= { _.todouble } val cc2= cc("second", 0.2) } def main(args: array[string]) { // works println("%s %f".format(works.cc1.name, works.cc1.getfrom("2.3"))) // fails println("%s %f".format(fails.cc2.name, fails.cc2.getfrom("4.5"))) } }
am doing illegal implicits?
i believe can answer what's happening here.. it's related other implicit conversions, , 1 created. if add trace can confirm stack overflow relates - function calling repeatedly until stack space of java crashes:
implicit val stringstodouble: string => double= { x=>println("called inner "+x); x.todouble }
.... called inner 4.5 called inner 4.5 called inner 4.5 called inner 4.5 called inner 4.5error: java.lang.stackoverflowerror
i think what's happening - todouble not natural function of java string, rather happens using implicit conversion in stringops (or stringlike, i'm not sure it's same issue).
so when call todouble - compiler starts seeking implicit conversion contain function "todouble". in theory resulting class.
but - should happen if several implicit conversions achieve this? unfortunately, "double" contains function todouble proven here:
val x = 44.4 x.todouble
and guess what? means new implicit function, closest in scope wins contest , get's called in circle accomplish "todouble" - trying turn string double, in order call todouble (on class double), repeatedly.. i'll admit it's confusing, evidence fits.
here's fix.. fits explanation , prevents recursive calls.
implicit val stringstodouble: string => double= { java.lang.double.parsedouble(_) }
Comments
Post a Comment