lua-users home
lua-l archive

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


2009/5/19 Richard Hundt <richardhundt@gmail.com>:
> You could of course borrow the following trick from PIL's section on weak
> tables:
>
> local func_meta = { }
> setmetatable(func_meta, { __mode = "k" })
>
> function setfmeta(func, meta)
>   func_meta[func] = meta
>   return func
> end
>
> function getfmeta(func)
>   return func_meta[func]
> end
>
> then if you want, you can override the native:
>
> -- upval access is faster than global lookup
> local type = type
> local setfmeta, getfmeta = setfmeta, getfmeta
> local setmeta, getmeta = setmetatable, getmetatable
>
> function setmetatable(that, meta)
>   if type(that) == "function" then
>      return setfmeta(that, meta)
>   end
>   return setmeta(that, meta)
> end
>
> function getmetatable(that)
>   if type(that) == "function" then
>      return getfmeta(that)
>   end
>   return getmeta(that)
> end

This doesn't work transparently, though, you have to be careful when
using this implementation as it will introduce memory leaks in the
presence of cycles.

###

local func_meta = { }
setmetatable(func_meta, { __mode = "k" })

function setfmeta(func, meta)
  func_meta[func] = meta
  return func
end

function getfmeta(func)
  return func_meta[func]
end

function memory_leak(f)
  return setfmeta(f, {__index = function () return f end})
end

weakbox = setmetatable({value = function () end}, {__mode = "v"})
collectgarbage("collect")
print(weakbox.value)

weakbox = setmetatable({value = memory_leak(function () end)}, {__mode = "v"})
collectgarbage("collect")
print(weakbox.value)

###

output:
> nil
> function: 0x804dae8

Ephemeron tables would solve this of course, if they are eventually implemented.

    Henk