lua-users home
lua-l archive

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


> That's why I suggested to have a new standard library "array". It
> won't be a new native Lua type. It's more or less just a standard
> metatable for array type tables. The only difference between an
> array and a sequence is, the array stores its length 'n' explicitly
> and therefore allows to have nils in it. Also the length is always
> set explicitly at construction or by calling setlength(n).
> 
> The metatable defines __len and __ipairs: The # oparator will always
> return n. The __ipairs always iterates from 1 to n, and doesn't care
> if there are nils in its way.
> 
> This is the minimal functionality needed. One could think of more
> options: You can override the __newindex to only accept keys between
> 1 and n. If setlength(new_n) is called, all elements after new_n
> become nil, if new_n < n. But these would just be extra features to
> make life easier.
> 
> It has been said, such solutions are already possible. So maybe the
> only thing left to do is to define the "standard" solution.

Is something like this enough? (Note that 'n' is *not* hidden; I do
not think hidden stuff is good in the end...)

-- Roberto

------------------------------------------------------------------------
-- Module 'array'
-- (tested lightly :)

local type, floor, pack, setmetatable, rawset =
  type, math.floor, table.pack, setmetatable, rawset

_ENV = nil

local array = {}

local nexti = function (t,i)
  i = i + 1
  if i <= t.n then
    return i, t[i]
  end
end


local mt = {
  __len = function (t) return t.n end,

  __newindex = function (t,k,v)
    if type(k) == "number" and k == floor(k) and k > t.n then
      t.n = k
    end
    return rawset(t,k,v)
  end,

  __ipairs = function (t) return nexti, t, 0 end
}

mt.__index = array


function array.new (...)
  local a = pack(...)
  setmetatable(a, mt)
  return a
end


function array.setlength (t, n)
  if n < t.n then
    for i = n + 1, t.n do t[i] = nil end
  end
  t.n = n
end


return array

local type, floor, pack, setmetatable, rawset =
  type, math.floor, table.pack, setmetatable, rawset

_ENV = nil

local array = {}

local nexti = function (t,i)
  i = i + 1
  if i <= t.n then
    return i, t[i]
  end
end


local mt = {
  __len = function (t) return t.n end,

  __newindex = function (t,k,v)
    if type(k) == "number" and k == floor(k) and k > t.n then
      t.n = k
    end
    return rawset(t,k,v)
  end,

  __ipairs = function (t) return nexti, t, 0 end
}

mt.__index = array


function array.new (...)
  local a = pack(...)
  setmetatable(a, mt)
  return a
end


function array.setlength (t, n)
  if n < t.n then
    for i = n + 1, t.n do t[i] = nil end
  end
  t.n = n
end


return array