[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Functions with individual metatables
- From: Henk Boom <henk@...>
- Date: Tue, 19 May 2009 09:26:24 -0400
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