Skip to content

Instantly share code, notes, and snippets.

@nefftd
Created October 7, 2014 17:06
Show Gist options
  • Save nefftd/70ca8fe12f4a1803bba6 to your computer and use it in GitHub Desktop.
Save nefftd/70ca8fe12f4a1803bba6 to your computer and use it in GitHub Desktop.
-- READ ONLY FORM
local mt = {} -- The real metatable
local mt_proxy = {} -- The object returned by getmetatable()
setmetatable(mt_proxy,{
__index = function(self,k) return mt[k] end, -- Allow the proxy to read fields. use a function so it's opaque (user cannot access real metatable)
__newindex = function() end, -- But writing is a nop (__newindex must exist, otherwise we may accidentally barr access to __index fields)
__metatable = false, -- Do not allow user code to overwrite the behavior of the proxy
})
mt.__metatable = mt_proxy -- Make getmetatable() return the proxy
test = {}
setmetatable(test,mt)
mt.__newindex = print -- insert into real metatable
assert(getmetatable(test).__newindex ~= nil) -- we can access the field
getmetatable(test).__newindex = function(...)
print('overruled',...)
end -- this should be discarded because this form is read-only
test[1]=1 -- should invoke the standard print, not 'overruled'
assert(not pcall(setmetatable,test,nil)) -- setting metatable should error
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment