Skip to content

Instantly share code, notes, and snippets.

@stevedonovan
Created December 30, 2010 08:20
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stevedonovan/759589 to your computer and use it in GitHub Desktop.
Save stevedonovan/759589 to your computer and use it in GitHub Desktop.
This defines an array with strict bounds checking. It is also impossible to set any existing index to a nil value, so the array remains free of holes. The table functions will not work on such arrays because they are userdata, giving an extra layer of pro
local function out_of_range(i,n)
if type(i) == 'number' then
if i > 0 and i <= n then return true
else error('out of range',3)
end
else
error 'cannot index array by non-number type'
end
end
function safe_array(n,val)
local array = {}
if n then
val = val or 0
for i = 1,n do array[i] = val end
end
local obj = newproxy(true)
local MT = getmetatable(obj)
function MT.__index(o,i)
out_of_range(i,#array)
return array[i]
end
function MT.__newindex(o,i,v)
-- note that assignment to array[#array+1] is permissible!
out_of_range(i,#array+1)
if v == nil then error('cannot assign nil',2) end
array[i] = v
end
function MT.__len(t)
return #array
end
return obj
end
obj = safe_array()
for i = 1,10 do
obj[i] = 10*i
end
for i = 1,#obj do print(i,obj[i]) end
-- table.insert(obj,10) can't use table functions on userdata!
-- obj[16]=10 --out of range
--obj[5] = nil -- cannot assign nil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment