Lua 5.1 workaround for __gc metadata for tables

I am currently facing the problem that you cannot use the method __gc

for tables in Lua 5.1 as they are implemented in Lua 5.2. However, I want to release the allocated resources as soon as the lua table is built. Is there a workaround that gives me the metatet functionality __gc

in Lua 5.2 for Lua 5.1?

+3


source to share


1 answer


In lua 5.1, the only lua values ​​that work with a metamethod __gc

are userdata

. Naturally, any hack or workaround has to be enabled in some way userdata

. There is usually no way to just create newuserdata from the lua side, but there is one "hidden" undocumented function for that newproxy

.

newproxy

accepts an optional bool or userdata parameter. If you go to true

, then you will get the user data with the new meta tag added. If you pass in a different one userdata

, then the new userdata will be assigned the same meta-metat as the one that was passed.

So now you can just hack a function that will make __gc

tables work:

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)

      

IDEOne Demo

Note that lua 5.2+ and later don't have it anymore newproxy

, as it is __gc

officially supported in tables.

+3


source







All Articles