9.9 Serializables
A serializable value is one of the predefined serializable datatypes (numbers, strings, lists, etc.; see Serializable) or an instance of a class that is declared with a serializable clause. The rhombus/serialize module provides functions for serializing and deserializing values.
class clause | ||||||||||||||||||||||||
| ||||||||||||||||||||||||
class clause | ||||||||||||||||||||||||
| ||||||||||||||||||||||||
| ||||||||||||||||||||||||
|
When serializable is declared without any options, the class must declare no uninitialized private fields. An instance is serialized by extracting and serializing all of its public fields, and it is deserialized by calling the class’s constructor. The constructor is called using the convention of a default constructor, but the class can have a custom constructor that accepts the same arguments.
When serializable is declared with options, each option must use a distinct keyword to customize serialization or deserialization:
~version: Determines the name of a submodule that exports the deserialization function. By incrementing the version past its default of 0 and explicitly declaring a submodule with the name corresponding to an older version, data from older serializations can be supported while modifying a class’s fields. See deserializer for more information about deserializer submodules.
~serialize: Provides a custom serialization function as an entry point. The entry point is like a method, and it must accept zero arguments; this, field names, etc., are bound within the entry point for the object being serialized. The result must be an array containing the object’s content, and the array’s content will be recursively serialized. The default serializer creates an array that has each constructor field’s value in the order that the fields are declared. A custom serialization entry point must be provided if a class has any private fields without default values.
~deserialize: Provides a custom deserialization function as an entry point. The entry point must accept as many arguments as elements of the vector produced by the serialization entry point. The default deserializer passes the arguments on to the class’s constructor following the class’s default constructor protocol (potentially using keyword arguments).
~deserialize_shell and ~deserialize_fill: Optional deserialization support for mutable objects that may have reference cycles. If either of these options is specified, then ~deserialize, ~deserialize_shell, and ~deserialize_fill must all be specified. The ~deserialize_shell entry point must accept zero arguments and return an object that will serve as the deserialized object. The ~deserialize_fill entry point must accept two arguments: the object returned by ~deserialize_shell’s entry point and an object generated by ~deserialize’s entry point to hold the final content; the ~deserialize_fill entry point should copy content from the latter to the former, and its result is ignored. If ~deserialize_shell and ~deserialize_fill are not specified, then objects with reference cycles involving only such objects cannot be serialized. The ~deserialize_shell and ~deserialize_fill entry points will be used only when serialized data contained cycles.
9.9.1 Serialization and Deserialization
import: rhombus/serialize | package: rhombus-lib |
annotation | |
The following pre-defined datatypes are serializable:
booleans, numbers, characters, interned symbols, unreadable symbols, keywords, strings, byte strings, paths (for a specific convention), regexp values, and #:void;
lists, arrays, boxes, maps, sets, pairs, and pair lists.
The byte-string encoding produced by serialize is independent of the Racket and Rhombus version, except as future versions introduce extensions that are not currently recognized.
function | |
|
declaration | ||||||||||||
| ||||||||||||
| ||||||||||||
|
The enclosing submodule normally should have a name of the form deserialize_Name_version where Name is the name of a serializable class declared in the submodule’s parent, and version is the class’s old version.
The intent of a deserializer is that the ~deserialize entry point accepts the content of an old-version object and returns a current-version object corresponding the the old object. For example, default values may be used for fields added in a newer version of the class.