#1263 Serialization of List/Map fields always use field type

go4 Sun 24 Oct 2010

List type inference

I get a ObjDecoder error:

class Main{
  static Void main(){
    obj:=TestObj{list=[,]}
    sb:=StrBuf()
    sb.out.writeObj(obj)
    echo(sb)//there is ok
    nobj:=sb.toStr.in.readObj
  }
}

@Serializable
class TestObj{
 Str[]? list
}

error:

sys::IOErr: Cannot set field Temp2_0::TestObj.list: sys::ArgErr: Wrong type for
field Temp2_0::TestObj.list: sys::Str[]? != sys::Obj?[] [Line 1]
  fanx.serial.ObjDecoder.err (ObjDecoder.java:656)
  fanx.serial.ObjDecoder.complexSet (ObjDecoder.java:338)
  fanx.serial.ObjDecoder.readComplex (ObjDecoder.java:250)
  fanx.serial.ObjDecoder.readObj (ObjDecoder.java:146)
  fanx.serial.ObjDecoder.readObj (ObjDecoder.java:55)
  fan.sys.InStream.readObj (InStream.java:546)
  fan.sys.InStream.readObj (InStream.java:543)
  Temp2_0::Cache.main (/D:/Temp/fan/Temp2.fan:23)
  java.lang.reflect.Method.invoke (Unknown)
  fan.sys.Method.invoke (Method.java:536)
  fan.sys.Method$MethodFunc.callList (Method.java:182)
  fan.sys.Method.callList (Method.java:147)
  fanx.tools.Fan.callMain (Fan.java:135)
  fanx.tools.Fan.executeFile (Fan.java:88)
  fanx.tools.Fan.execute (Fan.java:34)
  fanx.tools.Fan.run (Fan.java:236)
  fanx.tools.Fan.main (Fan.java:274)
Cause:
  sys::ArgErr: Wrong type for field Temp2_0::TestObj.list: sys::Str[]? != sys::Obj?[]
    fan.sys.Field.set (Field.java:128)
    fan.sys.Field.set (Field.java:104)
    fanx.serial.ObjDecoder.complexSet (ObjDecoder.java:334)
    fanx.serial.ObjDecoder.readComplex (ObjDecoder.java:250)
    fanx.serial.ObjDecoder.readObj (ObjDecoder.java:146)
    fanx.serial.ObjDecoder.readObj (ObjDecoder.java:55)
    fan.sys.InStream.readObj (InStream.java:546)
    fan.sys.InStream.readObj (InStream.java:543)
    Temp2_0::Cache.main (/D:/Temp/fan/Temp2.fan:23)
    java.lang.reflect.Method.invoke (Unknown)
    fan.sys.Method.invoke (Method.java:536)
    fan.sys.Method$MethodFunc.callList (Method.java:182)
    fan.sys.Method.callList (Method.java:147)
    fanx.tools.Fan.callMain (Fan.java:135)
    fanx.tools.Fan.executeFile (Fan.java:88)
    fanx.tools.Fan.execute (Fan.java:34)
    fanx.tools.Fan.run (Fan.java:236)
    fanx.tools.Fan.main (Fan.java:274)

I try on fansh:

fansh> Str[] names:=[,]
[,]
fansh> names.typeof
sys::Obj?[]

rosarinjroy Mon 25 Oct 2010

Please modify list=[,] to list=Str[,]. It should work. The modified code is given below:

class Main{
  static Void main(){
    obj:=TestObj{list=Str[,]}
    sb:=StrBuf()
    sb.out.writeObj(obj)
    echo(sb)//there is ok
    nobj:=sb.toStr.in.readObj
  }
}

@Serializable
class TestObj{
  Str[]? list
}

go4 Mon 25 Oct 2010

Thank you. I'am confused there is no error until serialize

brian Mon 25 Oct 2010

Okay first off, it may just be terminology but I think it is important to clarify: there is no type inference on field assignment except in a field initializer:

Str[] f := [,]    // f is Str[]
instance.f = [,]  // f is Obj?[]

The latter is not type inference, it is auto-casting in that we let you upcast an Obj?[] to a Str[]. It is important distinction because if you call typeof on the list it will be Obj?[], not Str[]. This is similar to Java in that you can downcast an arry, but the getClass() will still report the declaration type.

That said, I believe there was a bug in the serialization code. Actually it wasn't a bug so much as poorly chosen semantics. I originally maintained the list/map type if it was different from the declared field type. That is not the best choice for various reasons since it doesn't combine well with auto casting (as this issue shows). So I think the correct semantics are to always encode a list/map field with the type inferred by the field type.

brian Mon 25 Oct 2010

Renamed from List type inference to Serialization of List/Map fields always use field type

brian Mon 25 Oct 2010

Promoted to ticket #1263 and assigned to brian

brian Mon 25 Oct 2010

Ticket resolved in 1.0.56

Pushed a fix - changeset

Login or Signup to reply.