I’m working on a project in Lua where I will be creating tables and storing them in a master table, to be erased at a later time. I will pass around references to these tables to other sibling tables.
master = {}
table.insert(master, {name = 'hello'})
table.insert(master, {name = 'world', pre = master[1]})
The problem that occurs is that when I wish to erase the reference from the master table, the reference still remains in master[2] here. Obviously my first solution was to make the tables have weak values. (through .__mode on a metatable, not shown here)
This worked, and would work, so long as I would never store a singly-referenced table within these tables.
table.insert(master, {name = 'goodbye', pre = master[2], some_table = {123}})
The third element, some_table would eventually be collected, because the tables have weak values, and this table (some_table) is not referenced anywhere else. This is undesired behavior. My latest solution involves creating “weak reference objects” to the tables within the master table. A naive implementation follows:
function WeakRef(t)
r = {__mode = 'v', __index = t, __newindex = t}
setmetatable(r, r)
return r
end
These weak reference objects act similarly to boost::weak_ptrs and accomplish my goal, but I am uncertain if they are the best solution to my problem.
Is there a better way; a more elegant solution?
Is my design, which requires this master table, perhaps flawed?
Given that:
Then probably the simplest architecture is reserving one of the members of each object as a “middle man” in charge of managing the references to others. Here’re the steps:
mastera regular table (not weak)links(or whatever name suits your logic better)linkstables weak. Use them to store references to other objects.And this is a possible implementation. I’ve tried it in Lua 5.1: