To expand on iiiGodRoblox's answer
Arrays
and dictionaries
usually cannot be printed in a human readable format if just printed to console or tostringed.
tostring(table t)
will return some weird string that we know is table: some hexadecimal number
, but that doesn't really give a lot of information about the table, sure it's nice that we can print it but it's not really too useful to use right now.
For us to actually view and inspect an array
or dictionary
, we can either use some that returns the table as a string or __tostring
metamethod.
How To Implement
If you're bored of reading and just want an easy solution, you can use
1 | local function DumpTable(t) |
3 | for Index, Value in pairs (t) do |
4 | table.insert(str, tostring (Value)) |
6 | return "{" .. table.concat(str, ", " ) .. "}" |
It's not necessarily the best solution, but it works and it's simple enough to understand at a glance.
If you're curious for more information, you can keep on reading.
There's an obvious problem with the code above, it doesn't support nested tables; let's say we have a table structured as such
What our code above might output would be something along the lines of {World, table: 0xBAADF00D, table: 0xFFFFFF}
Yeah, it prints it out but now we're back to our original problem, it's printing table: hex
again.
What we can do is have some kind of recursive implementation that checks the type of Value
and if it's a table
, then dump that table
The code may fall something along the lines like
01 | local function DumpTable(t) |
03 | for Index, Value in pairs (t) do |
04 | if type (Value) = = "table" then |
05 | table.insert(str, DumpTable(Value)) |
07 | table.insert(str, tostring (Value)) |
10 | return "{" .. table.concat(str, ", " ) .. "}" |
If we inspect the code, we can see that it'll handle tables inside tables and tables inside those tables correctly.
Self referential tables
This should be enough for most people, but what if you're really eccentric and have something like
Now, at first, this may seem to work, its just tables inside tables but now this presents another problem: self-referential tables
This is what our little function will do
Now that's a problem, it just keeps on dumping a
and b
! This will go on infinitely and will cause a stack overflow which isn't good for both us and the computer.
What we can do to solve this is keep track of the tables that we already turned into strings, if it hasn't then do whatever we usually do, else just return tostring(t)
01 | local function DumpTable(t, Printed) |
02 | Printed = Printed or { } |
08 | for Index, Value in pairs (t) do |
09 | if type (Value) = = "table" then |
10 | table.insert(str, DumpTable(Value, Printed)) |
12 | table.insert(str, tostring (Value)) |
15 | return "{" .. table.concat(str, ", " ) .. "}" |
Now, this is what our function will do with the table a
and b
problem:
03 | -> DumpTable(b, Printed) |
05 | -> DumpTable(a, Printed) |
06 | -> a is in Printed, return tostring (a) |
07 | -> return "{" .. tostring (a) .. "}" |
08 | -> return "{{" .. tostring (a) .. " } } |
10 | DumpTable(a) = = "{{" .. tostring (a) .. "}}" |
This may seem not that useful but that's just because it isn't necessarily the best example; however, it clearly illustrates that, yes, it can handle self-referential tables while not having a stroke and dying.
Of course, this doesn't solve all our problems, it shows strings as String
rather than "String"
, which isn't optimal and while yes it works with both arrays
and dictionaries
, dictionary
support isn't exactly the best as it doesn't include the index. Using what you learned in this answer, try extending our code to work and solve these little problems.
If you want to use existing code to inspect tables, you can use Kikito's inspect.lua or my own table.FormatValue