DeepDive; An easy way to analyse the full contents of a table

Tables; whichever way you look at it, however which way you use them, they’re incredibly useful.
They can store bulks of information, are simple to access and easy to work with.

Well, until an entry doesn’t seem to exist…
or an entry isn’t what you thought it was…
or you’ve passed it over a remote, but some of the values aren’t there, or aren’t the same as on the server…
or you reference a table inside your table, but the reference to that table isn’t right, or it is and the keys inside don’t match what you thought it was, and then you’ve got to…

Keeping track of more complex tables gets complicated fast. Smaller tables are easier to keep track of, but once the entries start getting more complex, debugging can be a bit of a nightmare.

Sometimes its best to just look at the table itself.
To that end, I give you DeepDive, a debugging function that iterates through any given table, printing its full contents in an indented and formatted fashion. It’s all a single-string print, so other prints won’t impact the final result.

Just copy+paste the code into a ModuleScript, keeping it wherever is most accesible, and call it if you’re finding a problem is occuring.

DebugModule Code
local Debugging = {}

function IsEmpty(tbl)
    local HasContents = false
    for _,_ in pairs(tbl) do
        HasContents = true
        break
    end
    
    return HasContents
end

function Debugging.DeepDive(Name, tbl, Depth)
    local PreviousTables = {}

    function DeepDive(Name, tbl, Depth)
        local OurList
        if tonumber(Name) then
            OurList = "["..Name.."] = {"
        else
            OurList = Name.." = {"
        end
        local HasContents = IsEmpty(tbl)
        if HasContents == false then
            warn("Table is empty")
            return OurList.."}"
        elseif PreviousTables[tbl] then
            warn("Cyclicle table structure")
            return OurList..' "Table references earlier table, see entry: '..PreviousTables[tbl]..'" }'
        end
        PreviousTables[tbl] = Name
        OurList = OurList.."\n"
        for Key, Value in pairs(tbl) do
            if type(Value) == "table" then
                local StepDepth = Depth + 1
                OurList = OurList..string.rep("\t", StepDepth)..DeepDive(Key, Value, StepDepth)..";".."\n"
            elseif Value ~= nil then
                local isNumber = tonumber(Value)
                local isBool = tostring(Value) == "false" or tostring(Value) == "true"
                local OurValue = isNumber and tostring(Value) or isBool and tostring(Value) or '"'..tostring(Value)..'"'
    
                local KeyIsNumber = tonumber(Key)
                if not KeyIsNumber then
                    OurList = OurList..string.rep("\t", Depth + 1)..Key.." = "..OurValue..";".."\n"
                else
                    OurList = OurList..string.rep("\t", Depth + 1).."["..Key.."] = "..OurValue..";".."\n"
                end
            end
        end
        if Depth == 0 then
            print(OurList.."}")
        else
            return OurList..string.rep("\t", Depth).."}"
        end
    end

    DeepDive(Name, tbl, Depth)
end

return Debugging

Example use-case, checking the default data a player will receive

This is my table, + the DeepDive function call;

image

Output

image

Output copy + pasted into a script.

image

Ofcourse, this is intended to be used for tables that aren’t clearly laid out, but it’s always useful to see what the DeepDive actually finds via these prints.

In the future, I intend to include flags for common table related problems, like flagging the improperly formatted array (Bonus points to those of you who spotted it), if an object can’t be passed over remotes, or if any of the values won’t be able to be saved into a DataStore.

Is there any more information that should be included in the print? Are there any more common problems that this should warn against?

Look forward to hearing what you all make of this! :slight_smile:

7 Likes

Hi, @edenojack ~

Thank you for sharing your Tools with us, this is very interesting stuff

However we kind of already have this module:

What are the pros and cons; benefits of using your module over the OG one?


You also didn’t provide any links to your module as a model, file, or pastebin

I suggest that “The DebugModule” should also be changed to “Source Code”

This is purely designed to look at tables. Down the line theres additional functionality I’d like to add, with the examples given being the ones I can think of currently. Although thank you for pointing that out, I’d not seen that before!
I’ve yet to need that additional functionality, so I haven’t added it. This is just a personal module I’ve been using for a while, thought it’d be useful.

The entire module’s code is 60 lines, available to copy directly in the post. I’ve not had a problem with this system in the past, is pastebin a better alternative?

This is much better than my current table dumping script! I will be using this from now on.

1 Like

Glad to hear it’ll be useful! Is there any additional information you’d want to know about the tables/sub-tables when reviewing?

In addition to Stringify, there’s also repr which is specifically for tables:


I personally don’t see the point in this module as-is, over something I can easily trust to require by id, but I’m curious what new functionality is planned.

2 Likes