[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: new "empty" value/type in Lua?
- From: Roberto Ierusalimschy <roberto@...>
- Date: Tue, 2 Jul 2013 15:57:19 -0300
> 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