scala / pickling

Fast, customizable, boilerplate-free pickling support for Scala
lampwww.epfl.ch/~hmiller/pickling
BSD 3-Clause "New" or "Revised" License
831 stars 79 forks source link

Issues with recursive structures #102

Closed fancellu closed 10 years ago

fancellu commented 10 years ago

Compiles file, pickles fine, stack overflow on unpickle

import scala.pickling._
import json._

object Pick1 extends App {
  case class Person(name:String, age:Int, li:List[Int], var parent:Person)

  val mum=Person("Mum",69,Nil,null)
  val me=Person("Me",47,List(1,2,99),mum)  
  mum.parent=me  
  val out=me.pickle  
  println(out)  
  val in=out.unpickle[Person]  
  println(in)
}

JSONPickle({
  "tpe": "pickling.Pick1.Person",
  "name": "Me",
  "age": 47,
  "li": {
    "tpe": "scala.collection.immutable.$colon$colon[scala.Int]",
    "elems": [
      1,
      2,
      99
    ]
  },
  "parent": {
    "name": "Mum",
    "age": 69,
    "li": {
      "tpe": "scala.collection.immutable.Nil.type"
    },
    "parent": { "$ref": 0 }
  }
})

+

Exception in thread "main" java.lang.StackOverflowError
    at scala.runtime.ScalaRunTime$$anon$1.cmax(ScalaRunTime.scala:178)
    at scala.runtime.ScalaRunTime$$anon$1.hasNext(ScalaRunTime.scala:179)
    at scala.collection.Iterator$class.foreach(Iterator.scala:727)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
    at scala.collection.TraversableOnce$class.addString(TraversableOnce.scala:320)
    at scala.collection.AbstractIterator.addString(Iterator.scala:1157)
    at scala.collection.TraversableOnce$class.mkString(TraversableOnce.scala:286)
    at scala.collection.AbstractIterator.mkString(Iterator.scala:1157)
    at scala.runtime.ScalaRunTime$._toString(ScalaRunTime.scala:170)
    at pickling.Pick1$Person.toString(Pick1.scala:7)
    at java.lang.String.valueOf(String.java:2854)
etc
ScalaWilliam commented 10 years ago

:+1:

Also double recursion, e.g. A referring to B, B referring to C, and C referring to A.

phaller commented 10 years ago

Note that you're invoking toString via println here which is the method that produces the stack overflow. Can you try accessing fields of the unpickled instance without printing it? It might not be an issue related to pickling. Thanks!

fancellu commented 10 years ago
  val in=out.unpickle[Person]

  println (in.name)
  println (in.parent.name)

Works fine. Of course, nothing to stop the println drilling to the centre of the earth! What did I expect to see?

Thanks.

phaller commented 10 years ago

Good to hear it works. Thanks for your quick response!