I am writing a package with an S4 class that looks like a simple tree structure: the class, say S4node
, has a slot nodes
which is a list of child S4node
(via a common virtual ancestor, say S4base
). The class also has a slot parent
of type S4base
that links back up to the parent of the child nodes. That looks more-or-less like this (with barebones coding for clarity):
# Create the root node, slot parent is set to NA, slot id is set to 567
> root <- new_node(567)
# Create some child nodes, slot parent is set to root, slot nodes has new node added
> root <- add_node(root, 5671)
> root <- add_node(root, 5672)
This works ok and all slots are set correctly. Traversing down the hierarchy works, as well as traversing up the hierarchy. But here is the problem: when I want to traverse up the hierarchy the nodes
slot is set to NULL
, which becomes obvious when traveling down some other branch. Like this:
> node5671 <- find_node(root, 5671)
# Now traverse 5671 -> 567 -> 5672
> node5672 <- node_travel(node5671, "../5672")
Error: path not found
On the console this becomes clearer:
> length(root@nodes)
[1] 2
> node5671@parent@id
[1] 567
> nodes5671@parent@nodes
NULL
# Best one yet: take the root node, get a child, get the parent (= root), get the nodes = NULL!!!
> root@nodes[[1]]@parent@nodes
NULL
It appears to me that the list with nodes is emptied automatically, but only when implicitly accessed: I can construct the list in the first place, only when referencing the list through a @parent
lookup is the list emptied. Is this to avoid endless recursion? Is it a quirk of gc()
? Is there a work-around for this?