Skip to content
This repository was archived by the owner on Feb 20, 2019. It is now read-only.

Unpickling a class with mutable Map doesn't work #106

Open
@cooljykim

Description

@cooljykim

steps (0.10.0)

scala> import scala.pickling._, Defaults._, json._
import scala.pickling._
import Defaults._
import json._

scala> class ClassTwo {
     |   val m = collection.mutable.Map[String, Int]()
     | 
     |   def add(key: String, value: Int) = {
     |     val currentValue = m getOrElse(key, 0)
     |     m(key) = currentValue + value
     |   }
     | 
     |   override def toString: String = {
     |     m.map(pair => pair._1 + "->" + pair._2).mkString("map: [", " , ", "]")
     |   }
     | }
defined class ClassTwo

scala>     val c2 = new ClassTwo()
c2: ClassTwo = map: []

scala>     c2.add("k1", 21)

scala>     c2.add("k2", 34)

scala> c2
res2: ClassTwo = map: [k2->34 , k1->21]

scala> c2.pickle.value
res3: String =
{
  "$type": "ClassTwo"
}

scala> res3.unpickle[ClassTwo]
res4: ClassTwo = map: []

scala> res4.m == c2.m
res5: Boolean = false

problem

scala> c2.pickle.value
res3: String =
{
  "$type": "ClassTwo"
}

At this point, we are already missing the elements.

notes

The test case should've added

    assert(c2.m === result.m)

original report

As you can see my test cases below, pickling/unpickling a class with an immutable Map works, but a class with a mutable Map does not seem to be working.
If this is a bug, is there any work-around solution, please?

Here's my test cases:

import org.scalatest.FunSuite
import scala.pickling._
import binary._

class ClassOne {
  val m: Map[String, Int] = Map("k1" -> 21)
  override def toString: String = {
    m.map(pair => pair._1 + "->" + pair._2).mkString("map: [", " , ", "]")
  }
}

class ClassTwo {
  val m = collection.mutable.Map[String, Int]()

  def add(key: String, value: Int) = {
    val currentValue = m getOrElse(key, 0)
    m(key) = currentValue + value
  }

  override def toString: String = {
    m.map(pair => pair._1 + "->" + pair._2).mkString("map: [", " , ", "]")
  }
}


class PickleBinarySuite extends FunSuite {

  // This works!
  test("Pickling/Unpickling a class with a immutable Map") {
    val c1 = new ClassOne()
    println("class1=" + c1)
    val bytes = c1.pickle.value
    val result = bytes.unpickle[ClassOne]
    println("result=" + result)

  }

  // This also works!
  test("Pickling/Unpickling a mutable map") {
    val mMap = collection.mutable.Map[String, Int]()
    mMap("k1") = 56
    mMap("k2") = 57
    println(mMap.map(pair => pair._1 + "->" + pair._2).mkString("mMap: [", " , ", "]"))

    val pVal = mMap.pickle.value
    val upMap = pVal.unpickle[collection.mutable.Map[String, Int]]
    println(upMap.map(pair => pair._1 + "->" + pair._2).mkString("upMap: [", " , ", "]"))
  }

  // This doesn't work.
  test("Pickling/Unpickling a class with a mutable Map") {
    val c2 = new ClassTwo()
    c2.add("k1", 21)
    c2.add("k2", 34)
    println("class2=" + c2)

    val bytes = c2.pickle.value
    val result = bytes.unpickle[ClassTwo]
    println("result=" + result)
  }

}

and, printed results:

class1=map: [k1->21]
result=map: [k1->21]

mMap: [k2->57 , k1->56]
upMap: [k2->57 , k1->56]

class2=map: [k2->34 , k1->21]
result=map: []  // the un-pickled map is empty

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions