Skip to content

Instantly share code, notes, and snippets.

@Deco
Created January 29, 2012 10:35
Show Gist options
  • Select an option

  • Save Deco/1698206 to your computer and use it in GitHub Desktop.

Select an option

Save Deco/1698206 to your computer and use it in GitHub Desktop.
table.weakref
do table.weakref -- protect against evil anti-GC indirect self-references
--[[ sample usage:
a = {}
b = {a = a}
a.b = table.weakref(b)
a, b = nil, nil
-- a and b *should* be collected
-- to use b from a.b:
print(a.b() == b)
]]
= function(t)
return setmetatable({__ref=t}, table._weakref_mt)
end
table._weakref_mt = {
__mode = "v", -- DE MAGICKS!
__call = function(self)
return rawget(self, "__ref")
end,
}
end
do table.weakproxy -- same as above, but with a metatable to make it transparent (warning: hacky!)
--[[ sample usage:
a = {}
b = {a = a}
a.b = table.weakproxy(b)
a, b = nil, nil
-- a and b *should* be collected
]]
= function(t)
return setmetatable({__ref=t}, table._weakproxy_mt)
end
table._weakproxy_mt = {
__mode = "v", -- DE MAGICKS!
-- __add = function(l, r) end, -- TODO: Implement table.reference_mt.__add
-- __sub = function(l, r) end, -- TODO: Implement table.reference_mt.__sub
-- __mul = function(l, r) end, -- TODO: Implement table.reference_mt.__mul
-- __div = function(l, r) end, -- TODO: Implement table.reference_mt.__div
-- __mod = function(l, r) end, -- TODO: Implement table.reference_mt.__mod
-- __pow = function(l, r) end, -- TODO: Implement table.reference_mt.__pow
-- __unm = function(self) end, -- TODO: Implement table.reference_mt.__unm
-- __concat = function(l, r) end, -- TODO: Implement table.reference_mt.__concat
__len = function(self)
return #rawget(self, "__ref")
end,
-- __eq = function(l, r) end, -- TODO: Implement table.reference_mt.__eq
-- __lt = function(l, r) end, -- TODO: Implement table.reference_mt.__lt
-- __le = function(l, r) end, -- TODO: Implement table.reference_mt.__le
__index = function(self, key)
return rawget(self, "__ref")[key]
end,
__newindex = function(self, key, value)
rawget(self, "__ref")[key] = value
end,
__call = function(self, ...)
rawget(self, "__ref")(...)
end,
__tostring = function(self)
return tostring(rawget(self, "__ref"))
end,
}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment