lua-users home
lua-l archive

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

Title: RE: Implementing read only tables using C API


That is the same example from PiL2 that I mentioned :)

The reason I am doing this is to create a Lua script environment for some end users.  The point of the exercise is to create a simplistic environment in which they can write small lua script functions to perform operations on C objects.  I could just cut and paste some Lua code to do the job, but then every script that gets written (and there are going to be lots) would need to import a library script.  I'm not keen on that approach if it can be avoided.

> -----Original Message-----
> From:
> []On Behalf Of Thomas Lefort
> Sent: 16 June 2006 16:28
> To: Lua list
> Subject: Re: Implementing read only tables using C API
> > 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:
> 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.