Reputation: 3596
I made a custom table using metatables that automatically tracks sizing when elements are added. It works very well and removes the need for the #
operator or the getn
function.
However it has a problem. If you call table.insert
, the function apparently never calls __index
or __newindex
. Thus, my table cannot know when elements are removed this way. I assume the problem is the same with table.remove
as well.
How can I either:
insert
and use my own function to do soinsert
is called on my table.Thanks
function Table_new()
local public = { }
local tbl = { }
local size = 0
function public.size()
return size
end
return setmetatable(public, {
__newindex = function(t, k, v)
local previous_v = tbl[k]
rawset(tbl, k, v)
if previous_v ~= nil then
if v == nil then
size = size - 1
end
elseif v ~= nil then
size = size + 1
end
end,
__index = tbl
})
end
local t = Table_new()
t[5] = "hi"
t[17] = "hello"
t[2] = "yo"
t[17] = nil
print(t.size()) -- prints 2
local z = Table_new()
table.insert(z, "hey")
table.insert(z, "hello")
table.insert(z, "yo")
print(z.size()) -- prints 1 -- why?
Upvotes: 2
Views: 803
Reputation: 72312
If you print k,v in __newindex, you'll see that k is always 1. This is because table.insert
asks for the size of table to find where to insert the value. By default, it's at the end. You should add a __len metamethod. But perhaps this defeats your purposes (which are obscure to me).
Upvotes: 1