dumptable
1--[[ 2 Author: Julio Manuel Fernandez-Diaz 3 Date: January 12, 2007 4 (For Lua 5.1) 5 6 Modified slightly by RiciLake to avoid the unnecessary table traversal in tablecount() 7 8 Formats tables with cycles recursively to any depth. 9 The output is returned as a string. 10 References to other tables are shown as values. 11 Self references are indicated. 12 13 The string returned is "Lua code", which can be procesed 14 (in the case in which indent is composed by spaces or "--"). 15 Userdata and function keys and values are shown as strings, 16 which logically are exactly not equivalent to the original code. 17 18 This routine can serve for pretty formating tables with 19 proper indentations, apart from printing them: 20 21 print(table.show(t, "t")) -- a typical use 22 23 Heavily based on "Saving tables with cycles", PIL2, p. 113. 24 25 Arguments: 26 t is the table. 27 name is the name of the table (optional) 28 indent is a first indentation (optional). 29--]] 30function table.show(t, name, indent) 31 local cart -- a container 32 local autoref -- for self references 33 34 --[[ counts the number of elements in a table 35 local function tablecount(t) 36 local n = 0 37 for _, _ in pairs(t) do n = n+1 end 38 return n 39 end 40 ]] 41 -- (RiciLake) returns true if the table is empty 42 local function isemptytable(t) return next(t) == nil end 43 44 local function basicSerialize (o) 45 local so = tostring(o) 46 if type(o) == "function" then 47 local info = debug.getinfo(o, "S") 48 -- info.name is nil because o is not a calling level 49 if info.what == "C" then 50 return string.format("%q", so .. ", C function") 51 else 52 -- the information is defined through lines 53 return string.format("%q", so .. ", defined in (" .. 54 info.linedefined .. "-" .. info.lastlinedefined .. 55 ")" .. info.source) 56 end 57 elseif type(o) == "number" or type(o) == "boolean" then 58 return so 59 else 60 return string.format("%q", so) 61 end 62 end 63 64 local function addtocart (value, name, indent, saved, field) 65 indent = indent or "" 66 saved = saved or {} 67 field = field or name 68 69 cart = cart .. indent .. field 70 71 if type(value) ~= "table" then 72 cart = cart .. " = " .. basicSerialize(value) .. ";\n" 73 else 74 if saved[value] then 75 cart = cart .. " = {}; -- " .. saved[value] 76 .. " (self reference)\n" 77 autoref = autoref .. name .. " = " .. saved[value] .. ";\n" 78 else 79 saved[value] = name 80 --if tablecount(value) == 0 then 81 if isemptytable(value) then 82 cart = cart .. " = {};\n" 83 else 84 cart = cart .. " = {\n" 85 for k, v in pairs(value) do 86 k = basicSerialize(k) 87 local fname = string.format("%s[%s]", name, k) 88 field = string.format("[%s]", k) 89 -- three spaces between levels 90 addtocart(v, fname, indent .. " ", saved, field) 91 end 92 cart = cart .. indent .. "};\n" 93 end 94 end 95 end 96 end 97 98 name = name or "__unnamed__" 99 if type(t) ~= "table" then 100 return name .. " = " .. basicSerialize(t) 101 end 102 cart, autoref = "", "" 103 addtocart(t, name, indent) 104 return cart .. autoref 105end