lua-users home
lua-l archive

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


>    For instance, I want to do something like:
> 
>    t = makeASpecialTable()
>    t[{a=1, b=2}] = 42
>    assert(t[{a=1, b=2}] == 42)

Here are my $.02:

-- special.lua

local pairs, setmetatable = pairs, setmetatable
local assert, type, tostring = assert, type, tostring
local sort = function(t)
  -- tostring can be any serializer
  table.sort(t, function(x, y) return tostring(x) < tostring(y) end)
end

module(...)

-- sorted-key table iterator
local sk = setmetatable({}, { -- sorted refs
  __index = function(t, k)
    local s = {}
    for kk in pairs(k) do
      s[#s + 1] = kk
    end
    sort(s)
    t[k] = s
    return s
  end,
  __mode = "k"
})
local function skpairs (t)
  local s, i = sk[t], 0
  return function()
    i = i + 1
    local k = s[i]
    local v = t[k]
    if v ~= nil then return k, v end
  end
end

function new ()
  local o = {}
  return setmetatable({}, {
    __newindex = function(_, k, v)
      assert(type(k) == "table")
      local i, n, h = 0, #sk[k], o
      for kk, kv in skpairs(k) do
        i = i + 1
        local t = h[kk]
        if t == nil then
          t = {}
          h[kk] = t
        end
        h = t
        t = h[kv]
        if t == nil then
          t = i == n and v or {}
          h[kv] = t
        end
        h = t
      end
    end,
    __index = function(_, k)
      assert(type(k) == "table")
      local v = o
      for kk, kv in skpairs(k) do
        v = v[kk]
        if v ~= nil then v = v[kv] end
        if v == nil then return nil end
      end
      return v
    end
  })
end


$ lua -lspecial
Lua 5.1.2  Copyright (C) 1994-2007 Lua.org, PUC-Rio
> t = special.new()
> t[{a=1, b=2}] = 42
> = t[{a=1, b=2}]
42

Cheers,
Luis.

-- 
A mathematician is a device for turning coffee into theorems.
        -- P. Erdos 

-- 
Luis Carvalho
Applied Math PhD Student
Brown University