I have a lot of classes that are instantiated by a container, and sometimes it is convenient to serialise them. Either to transport to / from a browser, or to use in complicated test cases.
Here is a simplified example:
@Serializable
const class Data {
@Transient
const TransientData transData
const Str coreData
new make(TransientData transData, |This| f) {
this.transData = transData
f(this)
}
}
const class TransientData { }
To deserialise, Fantom can use the it-block to set the const fields, and any provided args to call the ctor:
To make this work, the following needs to be applied:
diff -r 41d3fde11500 src/sys/java/fanx/serial/ObjDecoder.java
--- a/src/sys/java/fanx/serial/ObjDecoder.java Thu Apr 26 09:16:05 2018 -0400
+++ b/src/sys/java/fanx/serial/ObjDecoder.java Fri Apr 27 18:26:44 2018 +0100
@@ -232,12 +232,17 @@
boolean setAfterCtor = true;
try
{
- // if first parameter is an function then pass toSet
+ // if last parameter is an function then pass toSet
// as an it-block for setting the fields
- Param p = (Param)makeCtor.params().first();
- if (args == null && p != null && p.type().fits(Sys.FuncType))
+ Param p = (Param)makeCtor.params().last();
+ if (p != null && p.type().fits(Sys.FuncType))
{
- args = new List(Sys.ObjType).add(Field.makeSetFunc(toSet));
+ if (args == null)
+ args = new List(Sys.ObjType);
+ else
+ // ensure args is a generic Obj list
+ args = new List(Sys.ObjType).addAll(args);
+ args.add(Field.makeSetFunc(toSet));
setAfterCtor = false;
}
brianFri 27 Apr 2018
I like the idea, but seems a little kludgy to me since really you could have a tree of objects. For example if it a list of objects, then what? It won't nest well.
Not sure I have a concrete alternative proposal, but couple ideas:
don't do anything and set it after the fact using AtomicRef
maybe make it more callback based on a per object basis
SlimerDudeSat 28 Apr 2018
You could have a tree of objects, but inner objects tend to be the responsibility of their owner. It's the root object you're primariily converned with.
The current mechanism allows you to exclusively choose a list of ctor args or an it-block to set const fields. Given it is well documented that it-blocks must always appear at the end of the ctor paramter list, I'm simply saying, "Why not have both!?"
I'm not proposing a new feature, just an extension of what's there already. It doesn't preclude any future changes you might want to make.
For example if it a list of objects, then what?
I'm not sure I understand.
If your ctor has more params, you just pass more args to makeArgs as per usual:
@Serializable
const class Data {
new make(Obj arg1, Obj arg 2, |This| f) {
f(this)
}
}
buf.readObj( ["makeArgs" : [arg1, arg2]] )
brianWed 2 May 2018
Apologies - I had forgot how that worked in the root object case.
I wired up that change in both Java and JS versions and added a test suite. Let me know how that works for you
SlimerDudeThu 3 May 2018
Brilliant! Thanks.
The Java version works well. Not tried it in JS yet, but I'm very happy it's been patched there too!
SlimerDude Fri 27 Apr 2018
I have a lot of classes that are instantiated by a container, and sometimes it is convenient to serialise them. Either to transport to / from a browser, or to use in complicated test cases.
Here is a simplified example:
To deserialise, Fantom can use the it-block to set the const fields, and any provided args to call the ctor:
To make this work, the following needs to be applied:
brian Fri 27 Apr 2018
I like the idea, but seems a little kludgy to me since really you could have a tree of objects. For example if it a list of objects, then what? It won't nest well.
Not sure I have a concrete alternative proposal, but couple ideas:
SlimerDude Sat 28 Apr 2018
You could have a tree of objects, but inner objects tend to be the responsibility of their owner. It's the root object you're primariily converned with.
The current mechanism allows you to exclusively choose a list of ctor args or an it-block to set const fields. Given it is well documented that it-blocks must always appear at the end of the ctor paramter list, I'm simply saying, "Why not have both!?"
I'm not proposing a new feature, just an extension of what's there already. It doesn't preclude any future changes you might want to make.
I'm not sure I understand.
If your ctor has more params, you just pass more args to
makeArgs
as per usual:brian Wed 2 May 2018
Apologies - I had forgot how that worked in the root object case.
I wired up that change in both Java and JS versions and added a test suite. Let me know how that works for you
SlimerDude Thu 3 May 2018
Brilliant! Thanks.
The Java version works well. Not tried it in JS yet, but I'm very happy it's been patched there too!