pickling icon indicating copy to clipboard operation
pickling copied to clipboard

Pickling a complex type as String

Open manuelbernhardt opened this issue 9 years ago • 3 comments

Disclaimer: I'm not sure if what I am trying to do could in theory work, because I don't know enough about pickle theory.

I'm trying to pickle a Java class (org.bson.types.ObjectId) so that its JSON representation yields a String. That works. However, unpickling does not quite work as well because, I think, the field is recognised as String and the JSONPickleReader does not know what to do (I get a MatchError). Hinting it with a different type tag than FastTypeTags.String yields an empty result at pickle-time.

My belief is that the unpickling strategy would be influenced by the knowledge of a type encoded (in the case of JSON) in the $type field of the pickled format, hence if at unpickle time we know that a field should be of a certain type then there should be a means by which to call for the adequate unpickler. Or is my belief nonsense?

For reference, the working pickling and broken unpickling:

    def pickle(picklee: ObjectId, builder: PBuilder): Unit = {
      builder.hintStaticallyElidedType()
      // this probably needs to hint at ObjectId but then the stringPickler isn't thrilled and returns nothing
      builder.hintTag(FastTypeTag.String)
      stringPickler.pickle(picklee.toString, builder)
    }
    def unpickle(tag: String, reader: PReader): Any = {
      val oid = stringPickler.unpickle(tag, reader).asInstanceOf[String]
      new ObjectId(oid)
    }

manuelbernhardt avatar Feb 23 '15 16:02 manuelbernhardt

This may be helpful: https://github.com/sbt/serialization/blob/master/serialization/src/main/scala/sbt/serialization/pickler/JavaExtraPicklers.scala#L39

havocp avatar Feb 23 '15 16:02 havocp

Thanks for the hint @havocp but I'm afraid the trouble arises before my custom unpickler even has a chance to get called - I tried using a similar approach to the example (pushing hints, pinning them etc. - by the way is there anywhere I could read up on what the meaning of pushing, pinning, unpinning etc. is?) but to no avail, the JSONPickleReader blows up at https://github.com/scala/pickling/blob/e8e6e261a592b364c8d602b11b0174248018a1fa/core/src/main/scala/pickling/json/JSONPickleFormat.scala#L212 (at least this is the line reported in version 0.10, but it seems a bit odd as the type is elided so it shouldn't get there, I will retry with the latest version later on).

My unpickler doesn't seem to get called, at least I can't find a trace of it in the stacktrace.

manuelbernhardt avatar Feb 24 '15 09:02 manuelbernhardt

if you blow up there then I think your goal is to go here instead: https://github.com/scala/pickling/blob/e8e6e261a592b364c8d602b11b0174248018a1fa/core/src/main/scala/pickling/json/JSONPickleFormat.scala#L206

maybe build a small compilable test case to attach here.

there aren't docs for the hints stuff. If I knew what they should say, I'd write them. :-)

havocp avatar Feb 24 '15 17:02 havocp