Quantcast

Pickling cyclic structures

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Pickling cyclic structures

Yang-19
It seems that Scala's BytePickler cannot (even) pickle cyclic data
structures! Is this correct? Here's a simple test case (based on the
scala.io wiki page) that I came up with when experimenting with
BytePickler to see if it was what I needed. After having gone through
the wrapper-writing process, it makes a bit more sense to me why (at
least with the way the combinators are currently defined) this would
be a deal-breaker, but I'd just like to check with the Scala list to
be sure. Thanks.

import scala.collection.mutable._
import scala.io.BytePickle._

abstract class Val
case class ValA(s: Set[Val]) extends Val
case class ValB(s: String) extends Val
case class ValC extends Val {
 val map: Map[String,Val] = new HashMap()
 val name: String = "hello"
 override def equals(any: Any) = any match {
   case o@Obj() => this eq o
   case _ => false
 }
}

object Pickler2 {
 def aPickler: SPU[Val] =
   wrap((xs: List[Val]) => ValA(Set(xs: _*)),
        (t: Val) => t match { case ValA(s) => s.toList },
        list(valPickler))

 def bPickler: SPU[Val] =
   wrap(ValB,
        (t: Val) => t match { case ValB(s) => s },
        string)

 def cPickler: SPU[Val] =
   wrap((p: Pair[List[Pair[String,Val]], String])
        => { val c = ValC()
            c.map ++= p._1
            c },
        (t: Val) => t match { case c@ValC() => {c.map.toList, c.name} },
        pair(list(pair(string,valPickler)), string))

 def valPickler: SPU[Val] =
   data(
     (t: Val) => t match {
       case ValA(_)   => 0
       case ValB(_) => 1
       case ValC() => 2
     },
     List(() => aPickler, () => bPickler, () => cPickler))

 def main(args: Array[String]) = {
   val b = ValB("world")
   val a = ValA(Set(b))
   val c = ValC()
   c.map("a") = a
   c.map("b") = b
   c.map("c") = c // cycle of death

   val res = pickle(valPickler, c)
   val c2 = unpickle(valPickler, res)
   c2 match { case c2@ValC() => Console.println(c2.name + " " + c2.map("a")) }
 }
}
Loading...