lua-users home
lua-l archive

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


The __index and __newindex metamethods are only invoked when you try to access or modify a value that doesn't exist in that table. In this case, tt[2] has the value 'b', so the metamethods won't get called. Try accessing, say, tt[5].

To make read-only tables, try using a "proxy" table. Make an empty table and give it a metatable with __index and __newindex defined. Other code will use this "proxy" table, and since it's blank, any accesses will get caught by the metamethods. From those you can defer to the real table, hidden from the user, perhaps stashed away in the metamethods' upvalues:

> function make_controlled_table(real)
>> local proxy = {}
>> setmetatable(proxy, {__index = function(tab, key) return real[key] end, __newindex = function() error("unauthorized") end})
>> return proxy
>> end

> cant_touch_this = make_controlled_table({'a', 'b', 'c'})
> = cant_touch_this[1]
a
> = cant_touch_this[2]
b

> cant_touch_this[2] = "something else"
stdin:3: unauthorized
stack traceback:
        [C]: in function 'error'
        stdin:3: in function <stdin:3>
        stdin:1: in main chunk
        [C]: ?


On Mon, Jun 29, 2009 at 2:35 PM, Sean Riley <sean@metaplace.com> wrote:

This code doesn’t invoke the __index metamethod.

tt = {'a', 'b', 'cc'}

mt = {

  __newindex = function(table, key, value)

                    error("Attempt to modify read-only table")

                  end,

 __index = function(table, key, value)

                    error("Attempt to access read-only table")

                  end,

}

setmetatable(tt, mt)

tt[2] = 1


I don’t understand exactly why..

-------------------

Sean Riley

"All problems in computer science can be solved by another level of indirection", Butler Lampson, 1972