"TheEndless" wrote:
I think I found out why the FormatJSON function isn't published... Any objects with circular references will blow up the Roku.
Fun discovery (YAWRR)!
One would consider this a bug only if they think BRS shouldn't have a reboot command 8-)
Musings: JSON cannot per-se represent structures with data cycles. It covers only a subset of "directed acyclic graphs". Non-corrupt trees, to be more specific (tree data structure where the root has no parent and each other node has exactly 1 parent). If not obvious how those are related, imagine drawing dictionary's root as a node with edges (labeled with the keys) pointing to value nodes. Array node A will have edges (labeled 0, 1, ...) pointing to the values as nodes A[0], A[1]... and that's it.
The example gives is a corrupt tree - "corrupted" by a cycle. And that can be done even with a single node:
InfiniteLoop = {} 'Cupertino, CA 95014
InfiniteLoop.next = InfiniteLoop
formatJSON(InfiniteLoop)
But there can be acyclic corrupted tree too, for example this
BrightScript Debugger> A = [1]
BrightScript Debugger> t = {left:A, right:A}
BrightScript Debugger> ?formatJSON(t)
{"left":[1],"right":[1]}
This does not cause crash but the serialization does not represent the fact that both "left" and "right" were pointing to the same array (or node A has two parents, left and right). There are libraries that can correctly handle serialization of general directed graphs (e.g. Python's "pickle") but that's not really in JSON's job description. So it's the wrong thing to send such data to JSON.
The easiest way to wash hands is to document that the function works correct only for "proper trees". More elaborate one would be to change the code so during serialization it keeps track of already visited nodes (in a set/AA) and if a node is re-visited to blow up with "corrupt tree" error; that will take care of both cases above.
PS. Bonus
bug in formatJSON - it only seems to work for AAs, but not for lists. Not a proper JSON:
BrightScript Debugger> ?formatJSON([1,2,3])