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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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