lua-users home
lua-l archive

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


On Sat, Feb 23, 2013 at 6:03 PM, Alfredo Palhares
<masterkorp@masterkorp.net> wrote:
> Hello Lua-l wizards,
>
> I do not have much experience with lua, so here it goes my question:
>
> local t = {}
>
> local var
>
> local function getVar()
>   -- do some loic here
>   return var
> end
> local function setVar(value)
>   -- do somelogic to value
>   var = value
> end
>
> return t
>
> On another file
>
> local t = requite("t.lua")
>
> t.setVar(somevar)
> -- And so on.
>
> My question is:
> Is there a KISS way to use the table like.
> t.var = value
> varibale = t.var
>
> And that will call the functions set and get?
>
> Thanks for your time.
>
> --
> Regards,
> Allfredo Palhares
>

There is: the __index and __newindex metamethods. See
http://www.lua.org/manual/5.2/manual.html#2.4

myTable = {}
setmetatable(myTable, {
    __index = function(self, key)
        print(key, "was looked up")
        return rawget(self, key)
    end,

    __newindex = function(self, key, value)
        print(key, "was set to", value)
        rawset(self, key, value)
    end,
})

That will create a table that will report when a value is read or
written. HOWEVER, these metamethods are only called if the key is not
already present in the table. So:
myTable[1] = 'a' --will print a message
myTable[1] = 'b' --will NOT print a message

This is done for performance reasons; if you want to have the
metamethods fire even for existing keys, store the actual values in
another table, like:

myTable = {}
local myProxy = {}
setmetatable(myTable, {
    __index = function(self, key)
        print(key, "was looked up")
        return rawget(myProxy, key)
    end,

    __newindex = function(self, key, value)
        print(key, "was set to", value)
        rawset(myProxy, key, value)
    end,
})

Now every access to myTable will trigger the metamethods, because the
actual values are stored in myProxy instead. (Note also that myProxy
is an upvalue to the methods, so they'll still be able to see it when
they're called from another scope that can't see myProxy itself - this
is useful to keep the proxy table "hidden" where other code can't
reach it.)

-- 
Sent from my Game Boy.