lua-users home
lua-l archive

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

Hash: SHA1

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
  proxy.__index = function(self, key) -- reading
    return data[key]
  setmetatable(proxy, proxy)
  return proxy

Now all key accesses are routed via your code, which means the user gets
to do '' and you get to do whatever you like. Best of both worlds.

> I'm not sure how can this interfere with GC. If table is not
> referenced anywhere, it would be collected regardless of its contents.

Garbage collecting a distributed system is one of the classic Hard
Problems. (I don't know if there's a proper solution yet.) Most people
don't even try, and instead manage lifetimes manually. This requires you
to design your data structures to allow this, of course. The classic Lua
big-bag-of-data approach won't work --- we can't destroy object #1234 on
machine X until object #91872 on machine Y and object #173791 on machine
Z have stopped using it, and we may not be aware of any potential users.

An approach that I've seen used successfully is to divide objects up
into heavyweight and lightweight. Each heavyweight object has a global
ID. Lightweight objects are owned by exactly one heavyweight object and
are stored next to their owner. No heavyweight object can refer to a
lightweight object belonging to a different heavyweight object.


local o = FindHeavyweightObject("1234") = 1 = {1, 2, 3} -- the table here is a lightweight object
o.baz = FindHeavyweightObject("4567") = 1 = {1, 2, 3} = -- either illegal, or the table is copied by the proxy

Synchronisation is also fun. The simplest approach is to do all remote
accesses synchronously so that ever access involves a roundtrip --- but
that's expensive. Caching stuff locally is much faster but then you
start needing transaction blocks to manage concurrency, which can easily
become a nightmare.

- -- 
┌─── ───── ─────
│ "Sufficiently advanced incompetence is indistinguishable from
│ malice." -- Vernon Schryver
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla -