I'm currently facing the problem that you can't use the __gc
method for tables in Lua 5.1, as they are implemented in Lua 5.2. However, I want to release allocated native resources once the lua table gets collected. Is it possible to make a workaround which gives me the functionality of __gc
metamethod in Lua 5.2 for Lua 5.1?
In lua 5.1 the only lua values that work with __gc
metamethod is userdata
. Naturally any hack or workaround will have to involve userdata
in someway. Normally there is no way to just create newuserdata from the lua side but there is one "hidden" undocumented function newproxy
for doing just that.
newproxy
takes an optional bool or userdata parameter. If you pass in true
then you get a userdata with a new metatable attached. If you pass in another userdata
then the new userdata will be assigned the same metatable as the one passed in.
So now you can just hack together a function that'll make __gc
work on tables:
function setmt__gc(t, mt)
local prox = newproxy(true)
getmetatable(prox).__gc = function() mt.__gc(t) end
t[prox] = true
return setmetatable(t, mt)
end
And a quick test to confirm the behavior:
iscollected = false
function gctest(self)
iscollected = true
print("cleaning up:", self)
end
test = setmt__gc({}, {__gc = gctest})
collectgarbage()
assert(not iscollected)
test = nil
collectgarbage()
assert(iscollected)
Note that lua 5.2+ and later no longer have newproxy
since __gc
is officially supported on tables.