Hi together,
i have the following problem regarding the handling of tables in lua. In my program I often create tables in functions and save the returned table in a variable.
function new_table ()
-- local t = {}
t = {}
t.name = "test123"
t.clock_id = nil
t.run = function (self)
self.clock_id = clock.run(
function (s)
while true do
print(s.name)
clock.sleep(1)
end
end, self)
end
return t
end
function init ()
print("lua test project")
obj = new_table()
obj:run()
end
If I execute the above example I see the expected behavior, the print command is executed every second, printing the name field of obj.
If I try to delete obj via the console with obj = nil, I would expect that an error message should occur since the running clock function refers to a table which not longer exists, instead the “test123” is further printed.
Next, I tried to directly delete t since I assumed that obj is rather a “reference” to the “real” table. However, the behavior continues. If I check if t still exists, I can not longer reference t.
What is going on here? Is clock still referencing the original memory slot and therefore, still runs without errors? Is the memory trashed with seemingly deleted tables, which are created in functions?
I am aware that I simply should cancel the clock, but I am really interested in what is happening with the table to be deleted. While this is a super easy example to illustrate this problem, I found it in the context of deleting a big sequence of note data and the sequencer kept running in the background …
So it would be pretty bad if I would unconsciously overflow the memory, by not being able to delete such tables properly.
EDIT:
To fix the problem I tried to eliminate to pass the table to be deleted as a variable to the clock.run function.
function new_table ()
t = {}
t.name = "test123"
t.clock_id = nil
t.run = function (self)
self.clock_id = clock.run(
function (s)
while true do
print(s.name)
clock.sleep(1)
end
end, self)
end
return t
end
function init ()
obj = new_table()
--obj:run()
clock.run(function () while true do print(obj.name) clock.sleep(1) end end)
end
if I now delete obj with obj = nil, an error occurs.
Eliminating the variable in which the table is stored in new_table does not solve the problem.
function new_table ()
return {
name = "test123",
clock_id = nil,
run = function (self)
self.clock_id = clock.run(
function (s)
while true do
print(s, s.name)
clock.sleep(1)
end
end, self)
end
}
end
function init ()
obj = new_table()
print(obj)
obj:run()
-- clock.run(function () while true do print(obj.name) clock.sleep(1) end end)
end
If I print the table, the same address is returned. No matter if I refer to obj or to s inside the passed function.
Since passing variables to run is a feature, I think this could be a major issue for a lot of use cases.
Thanks for your help and your input!