72 lines
1.6 KiB
Lua
72 lines
1.6 KiB
Lua
function prettyPrint(value)
|
|
local function helper(val, indent, visited)
|
|
-- Handle non-tables and non-userdata
|
|
if type(val) ~= 'table' and type(val) ~= 'userdata' then
|
|
return tostring(val)
|
|
end
|
|
|
|
-- Detect cycles (tables or userdata)
|
|
if visited[val] then
|
|
return "{...}"
|
|
end
|
|
visited[val] = true
|
|
|
|
-- Check if it's iterable (table or userdata with __pairs)
|
|
local is_iterable = false
|
|
local iterator_func = nil
|
|
|
|
if type(val) == 'table' then
|
|
is_iterable = true
|
|
iterator_func = pairs
|
|
elseif type(val) == 'userdata' then
|
|
-- Check for __pairs metamethod (Lua 5.2+)
|
|
local mt = debug.getmetatable(val)
|
|
if mt and mt.__pairs then
|
|
is_iterable = true
|
|
iterator_func = mt.__pairs(val)
|
|
end
|
|
end
|
|
|
|
-- If not iterable, just return tostring
|
|
if not is_iterable then
|
|
visited[val] = nil -- Clean up visited
|
|
return tostring(val)
|
|
end
|
|
|
|
-- Build key-value pairs
|
|
local entries = {}
|
|
local nextIndent = indent + 1
|
|
for k, v in iterator_func(val) do
|
|
local keyStr = helper(k, nextIndent, visited)
|
|
local valStr = helper(v, nextIndent, visited)
|
|
local entry = string.rep(" ", nextIndent) .. keyStr .. ": " .. valStr
|
|
table.insert(entries, entry)
|
|
end
|
|
|
|
-- Format output
|
|
local result = "{\n"
|
|
if #entries > 0 then
|
|
result = result .. table.concat(entries, ",\n") .. "\n"
|
|
end
|
|
result = result .. string.rep(" ", indent) .. "}"
|
|
|
|
visited[val] = nil -- Allow reuse in different branches
|
|
return result
|
|
end
|
|
|
|
print(helper(value, 0, {}))
|
|
end
|
|
|
|
local test = {
|
|
numbers = { 1, 2, 3 },
|
|
nested = {
|
|
a = "apple",
|
|
b = { c = "cherry" }
|
|
},
|
|
func = function() end,
|
|
self = nil
|
|
}
|
|
test.self = test
|
|
|
|
prettyPrint(test)
|