[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: How can I hook into gc?
- From: "Nick Trout" <nick@...>
- Date: Wed, 19 Nov 2003 21:57:45 -0800
> Why can't you hook into the freeing of a regular old table via the
> metatable?
>
> I want to do this:
>
> -------------------------------------------
> z = {1,2}
> mymeta = {__gc = function() print("x cleanup") end, __index =
function()
> return 4 end }
> setmetatable(z,mymeta)
> print(z[1])
> print(z[8])
> print(z[8])
> z = nil
> collectgarbage()
> -------------------------------------------
>
> and see it go
>
>
> 4
> 4
> 4
> "x cleanup"
>
>
> but instead it laughs at me as if I am a fool. What it really prints
> is:
>
> 1
> 4
> 4
>
> So why the '1' - what about my __index function? I guess that only
> works if it can't find the thing in the table first -- which is ok for
> some things but sucks for other uses I might try to put __index to.
You have a 1 in your table. You need to use an empty proxy table to
always get a query. From the manual:
"index": The indexing access table[key].
function gettable_event (table, key)
local h
if type(table) == "table" then
local v = rawget(table, key)
if v ~= nil then return v end
h = metatable(table).__index
if h == nil then return nil end
else
h = metatable(table).__index
if h == nil then
error("...");
end
end
if type(h) == "function" then
return h(table, key) -- call the handler
else return h[key] -- or repeat operation on it
end
> And then of course, why no support for __gc invoking the function? Or
> am I somehow not preparing it for gc when I do the z = nil.
The __gc method only works for C data types. Search the lua-l archives
for the reason why. I can't remember why Lua types don't have gc
metamethods. Probably something to do with finalisation or userdata
being freed outside the GC.
> Suggestions? Helpful interpretations? Can I hook into the freeing of
a
> table somehow with the metatable, and if not why the heck not? :)
Put a metatable on the table enclosing the table whose destruction you
want to catch. Use the __index MM to watch for the table being assigned
to nil, then bingo. I think that'll work.
Nick