know whether an object is not deleted propally, to find any object tha can be messing with
your code or any other purpose that involves tracing the locations of an object.
Here it is:
Code: Select all
function traceObject(target,ignore,start)
local isarray = function(x)
return type(x) == "table" and x[1] ~= nil
end
local getiter = function(x)
if isarray(x) then
return ipairs
elseif type(x) == "table" then
return pairs
end
error("expected table", 3)
end
local function remove(t, x)
local iter = getiter(t)
for i, v in iter(t) do
if v == x then
if isarray(t) then
table.remove(t, i)
return true
else
t[i] = nil
return true
end
end
end
return false
end
local done = {}
local data = ""
local count = 0
local refs = {}
local gotten = {}
local printed = {}
if type(ignore)=="string" then
ignore = {_G, ignore}
else
ignore = {}
end
local function _traceObject(m,name)
done[tostring(m)] = true
local _printed = {}
local function check(x,i)
if i==target and not (x==ignore[2] and m==ignore[1]) then
if not gotten[tostring(m)..x] then
local sp = " "
gotten[tostring(m)..x] = 1
table.insert(refs,{name or "_G",m})
if not printed[tostring(m)] then
for cc = 1,#refs do
local r = refs[cc]
local name, value = r[1],r[2]
if not _printed[tostring(value)..name] then
data = string.format("%s\n%sMoving to index %s: ",data,sp,name)
sp = string.format("%s ",sp)
_printed[tostring(value)..name] = 1
end
end
printed[tostring(m)] = sp
end
sp = printed[tostring(m)]
data = string.format("%s\n%sFound target at index `%s`.",data,sp,x)
refs[#refs] = nil
end
elseif type(i)=="table" and not done[tostring(i)] then
local tt = {name or "_G",m}
local name = name or "_G"
table.insert(refs,tt)
_traceObject(i,x)
remove(refs,tt)
end
end
for x,i in pairs(m) do
check(x,i)
end
for x,i in ipairs(m) do
check(x,i)
end
return data
end
local data = _traceObject(start or _G)
if data=="" then
data = "Not Found!"
end
return data
end
traceObject(table object[, table ignore, table start])
table object: object(mostly table, can be other) that should be traced
table ignore: {table parent, string name}, ignore entries of key 'name' in parent
string ignore: ignores global variable put in ignore
table start: where to start tracing, defaults to _G
returns: string representing traces of where the object lies
Code: Select all
--example
t = {"hey"}
gotcha = {["that"]=t}
gotcha.forge = {hey={7,8,9,k={0,["that"]=t,["y"]={"can",t},nu={7,7,t}},t,t}}
--print traces ignoring key "that" at table gotcha
print(traceObject(gotcha.that,{gotcha,"that"}))
--print traces ignoring key "t" at global table
print(traceObject(gotcha.that,"t"))
--print all traces
print(traceObject(gotcha.that))
--print all traces starting from gotcha.forge
print(traceObject(gotcha.that,nil,gotcha.forge))
--print all traces of string "can"
print(traceObject("can,"t"))