lua-users home
lua-l archive

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


> So I was wondering if there was something like another callback
> metamethod for userdata, e.g. __mark(), that the garbage collector
> calls in order to decide if the userdata should be marked for
> collection.

I guess the following structure does what you want. Specifically,
once the object becomes garbage, it calls a user-defined function
('cancollect', in the example) to check whether the object can be
collected. Only when the answer is 'yes' will it call another specific
function ('collect', in the example) with the object and then actually
release the Lua object. (Note that you cannot use the __gc metamethod of
'myobject', as it will be called once the object becomes gargage; you
must use 'collect' to finalize the object.)

-- Roberto

-------------------------------------------------
local anchor = setmetatable({}, {__mode = "k"})

myobject = {name = "my object"}   -- object to be preserved


local function cancollect (obj)
  print("may I collect object " .. obj.name .. "?")
  return (io.read() == "yes")
end


local function collect (obj)
  print("collecting " .. obj.name)
end


local function mksentinel (obj)
  local sentinel = {}
  setmetatable(sentinel,
    {__gc = function (s)
              if not cancollect(obj) then
                mksentinel(obj)
              else
                collect(obj)
              end
            end})
  anchor[sentinel] = obj
  obj.sentinel = sentinel
end

mksentinel(myobject)


print(1); collectgarbage()
print(2); collectgarbage()
myobject = nil
print(3); collectgarbage()
print(4); collectgarbage()
print(5); collectgarbage()
print(6); collectgarbage()