|
May have discovered the issue, it's two-fold.1- I needed a metatable on the metatable to make it have weak-refs on __index/__newindex2- Weak refs are left until GCed (makes sense), so I'd need to invoke a full GC whenever I wanted to make sure the weak ref isn't accessibleExample:local EntityList = {}function main()EntityList[0] = { foo = "bar" }local EntityVar_mt_mt = { __mode = "kv" }local EntityVar_mt = { __index = EntityList[0], __newindex = EntityList[0] }setmetatable( EntityVar_mt, EntityVar_mt_mt )local EntityVar = {}setmetatable( EntityVar, EntityVar_mt )print(EntityVar.foo)EntityList[0] = nilcollectgarbage("collect")print(EntityVar.foo)endmain()On 1 June 2011 14:06, Chris Redden <kaelic@gmail.com> wrote:
When you say "If your metatable has weak values, then its entries will be cleared
when the values are no longer accessible." are you saying this includes metamethods?local EntityList = {}function main()EntityList[0] = { foo = "bar" }local EntityVar_mt = { __mode = "kv", __index = EntityList[0], __newindex = EntityList[0] }local EntityVar = {}setmetatable( EntityVar, EntityVar_mt )print(EntityVar.foo)EntityList[0] = nilprint(EntityVar.foo)endmain()In this example, I'd expect the following output:barnilbut I get:barbarOn 1 June 2011 13:27, Roberto Ierusalimschy <roberto@inf.puc-rio.br> wrote:
This 'fix' only prevents the collection of the strings '__add', '__index',> It seems all of the metamethods retain a strong reference, which is causing
> me problems trying to use proxy objects. Is there a specific reason they're
> a strong reference? It seems to be this line that makes them all strong:
>
> ltm.c: 39
> for (i=0; i<TM_N; i++) {
> G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
> luaS_fix(G(L)->tmname[i]); /* never collect these names */
>
> What would be the implications of removing this luaS_fix on the metamethods?
etc. (Anyway, strings are never removed by themselves from weak tables.)
If your metatable has weak values, then its entries will be cleared
when the values are no longer accessible.
-- Roberto