[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Metatables are "hard" (Re: Question about __index and classes)
- From: "Robert G. Jakabosky" <bobby@...>
- Date: Sun, 11 Sep 2011 14:03:23 -0700
On Sunday 11, Daurnimator wrote:
> On 12 September 2011 00:26, Richter, Jörg <Joerg.Richter@pdv-fs.de> wrote:
> >> In Lua you cannot sandbox a metatable away. An offending script still
> >> might just call getmetatable.
> >
> > Then use __metatable:
> >
> > http://www.lua.org/manual/5.1/manual.html#pdf-getmetatable
> >
> > Jörg
>
> As a note to using __metatable; its a good idea to return a
> string/object unique to each metatable.
> Its nice if code can use getmetatable() to check for type equality.
Here is one method for type checking that I have used, that also allows hiding
the metatable.
-- unique type key, not visible outside the object's implementation.
local object_key = {}
local mt = {
__metatable = false, -- hide metatable
}
-- Don't use metatable as __index, this would allow object_key to leak
-- to outside code.
-- -- mt[object_key] = mt
-- -- mt.__index = mt
-- code could call "pairs(obj.__index)" to find object_key.
-- if __index a different table
mt.__index = {
[object_key] = mt,
-- methods go here.
}
-- or if __index is a function
function mt.__index(obj, key)
-- put your normal __index function code here.
-- last check for object_key lookup
if key == object_key then return mt end
return nil -- key not found, maybe assert here about missing object method?
end
-- this type checking method could be made public.
function check_object_type(obj)
return (obj[object_key] == mt)
end
function new_object(init)
if init and check_object_type(init) then
-- init is already the correct type, Copy it?
return init -- just return it as-is
end
return setmetatable(init or {}, mt)
end
With this method no code outside the object's implementation can get the
object's type tag "object_key" or metatable and make a fake object.
--
Robert G. Jakabosky