lua-users home
lua-l archive

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


On Fri, Jan 8, 2010 at 1:10 PM, David Given <dg@cowlark.com> wrote:
>
> On 08/01/10 11:29, Alexander Gladysh wrote:
> [...]
>>>    3. I investigated the metamethod idea - there's no way to define a
>>> metamethod for changing an existing key, as in the above example. (Right?)
>>
>> As it was suggested, use a proxy table (put a metatable over an empty
>> table, but store all data elsewhere).
>
> I'll second what Alexander wrote --- proxies work really nicely,
> although they're a bit counterintuitive. Consider:
>
> function MakeProxy()
>  local data = {} -- all our data is actually stored here
>  local proxy = {} -- this is all the user sees
>  proxy.__newindex = function(self, key, value) -- assignment
>    data[key] = value
>  end
>  proxy.__index = function(self, key) -- reading
>    return data[key]
>  end
>  setmetatable(proxy, proxy)
>  return proxy
> end
>
> Now all key accesses are routed via your code, which means the user gets
> to do 'foo.bar' and you get to do whatever you like. Best of both worlds.

Be careful; proxies are not fully transparent in current Lua: pairs()
and ipairs() use raw table access so the metamethods are not invoked,
same thing for the length operator and a __len metamethod and also the
table library uses raw table access.
See http://lua-users.org/wiki/GeneralizedPairsAndIpairs and
http://lua-users.org/wiki/LuaVirtualization for the details.

-- 
Dirk