lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



> 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