lua-users home
lua-l archive

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


I would like to create a table within my app that is accessable to Lua scripts that just defines some values that can't be changed.
[...]
I can get an error on __newindex, but I don't know how to stop assignments to existing entries.

How about this example from PIL: http://www.lua.org/pil/13.4.5.html

There are no entries in the proxy, so __newindex will be fired upon
any write access.

I have PiL 2nd edition and in that it describes how to do it implement this from within a lua script itself and I have tried to implement this using the C API, but my understanding must be somewhat lacking as I can't quite get it to work.

Get it to work in pure Lua first, it's easier. Only then port it to
API code if deemed necessary.
For instance:

function createReadOnlyProxy(t)
 return setmetatable({}, {
   __index = t,
   __newindex = function() error("attempt to write read-only table") end,
   __metatable = "read-only table proxy"
 })
end

function test()
 local t0 = {toto = "toto"}
 local t = createReadOnlyProxy(t0)
 assert(t.toto)
 local function write(t, k, v) t[k] = v end
 assert(not pcall(write, t, "toto", "titi"))
 assert(not pcall(write, t, "titi", "titi"))
 assert(type(getmetatable(t)) == 'string')
 assert(not pcall(setmetatable, t))
end

The optional __metatable field prevents indirect access to the
original table. For full security, you will want to run user chunks in
sandbox environments, otherwise they might use rawset to write the
proxy.