lua-users home
lua-l archive

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

On Sunday 11, Daurnimator wrote:
> On 12 September 2011 00:26, Richter, Jörg <> wrote:
> >> In Lua you cannot sandbox a metatable away. An offending script still
> >> might just call getmetatable.
> > 
> > Then use __metatable:
> > 
> >
> > 
> >   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?

-- this type checking method could be made public.
function check_object_type(obj)
  return (obj[object_key] == mt)

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
  return setmetatable(init or {}, mt)

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