Pickle Self-Refrencing
December 15, 2017 ยท View on GitHub
Pickle Self-Refrencing
Pickling lists is complicated because they can contain the same list multiple times, or even have recursive lists:
var a = {'hello'}
var b = {a, a}
say b # {{'hello'}, {'hello'}}
var c = {'world'}
list.push c, c
say c # {{'world'}, {circular}}
List a is flat and doesn't contain duplicate references.
List b contains a sibling reference. Sibling references are when there exists multiple
non-circular references to the same object.
Sibling references can be serialized using JSON, but upon deserializing, the fact that
b[0] == b[1] will be lost:
var b2 = b | pickle.json | pickle.val
say b[0] == b[1] # 1 (true)
say b2[0] == b2[1] # nil (false)
List c contains a circular reference -- this is when a list contains itself somewhere inside of
it. Circular references cannot be serialized using JSON and will cause the sink script to abort in
failure.
The pickle.sibling and pickle.circular commands can test whether an object has sibling or
circular references. To avoid this problem completely, it's recommended to use the binary format
(via pickle.bin) in lieu of the JSON format, since it correctly handles restoring references
(both sibling and circular).