#2758 @Serializable, non-const classes, and it-block ctors

SlimerDude Wed 26 Jun 2019

When I try to de-serialise a non-const class with an it-block ctor, I get an error. Here's a side by side example with a const class:

@Serializable
const class ConstClass {
    const Str name
    new make(|This| f) { f(this) }
}

@Serializable
class NotConstClass {
    Str name
    new make(|This| f) { f(this) }
}

constClass    := ConstClass    { it.name = "wotever" }
notConstClass := NotConstClass { it.name = "wotever" }
	
serial1 := Buf().writeObj(constClass)
serial1.flip.readObj  // --> okay

serial2 := Buf().writeObj(notConstClass)
serial2.flip.readObj  // --> ERROR!

sys::ArgErr: Too few arguments: 0 < 1..1
  fan.sys.Method$MethodFunc.checkArgs (Method.java:520)
  fan.sys.Method$MethodFunc.callList (Method.java:206)
  fan.sys.Method.callList (Method.java:138)
  fanx.serial.ObjDecoder.readComplex (ObjDecoder.java:246)
  fanx.serial.ObjDecoder.readObj (ObjDecoder.java:146)
  fanx.serial.ObjDecoder.readObj (ObjDecoder.java:55)
  fan.sys.InStream.readObj (InStream.java:641)
  fan.sys.InStream.readObj (InStream.java:638)
  fan.sys.Buf.readObj (Buf.java:358)

It seems the it-block is being ignored because it is a normal class - but given the class has non-nullable fields, the it-block ctor is the only workable choice.

brian Fri 19 Jul 2019

That is the way its designed to work:

  • const class is always deserialized using it-block
  • non-const class always deserialized using no arg make() + field sets

SlimerDude Tue 10 Dec 2019

Hmm... what this implies then, is that ALL fields on @Serializable non-const classes MUST be nullable and non-const; which seems quite the oppressive limitation.

If a class has an it-block ctor, in what situation would you not want to use it?

brian Tue 10 Dec 2019

Not exactly. It means that non-const classes must have only mutable fields, but they can be non-nullable if you give them a default value.

Essentially the original design was for a mutable data class that let you do your sets via a text file. Then we added support for immutable classes using different mechanism via it-blocks. But its never going to work well to mix the two together. It was never intended to be an all encompassing format to do everything that Fantom allows in code. In fact, if I were do it again serialization would not even be included. I think the developer world has moved on from "pickling" objects to using standard language independent data formats like JSON, YAML, etc.

Login or Signup to reply.