Skip to content

Instantly share code, notes, and snippets.

@dk949
Last active February 25, 2025 10:51
Show Gist options
  • Save dk949/1f845945b7e58e7c3a2c9a8e92707110 to your computer and use it in GitHub Desktop.
Save dk949/1f845945b7e58e7c3a2c9a8e92707110 to your computer and use it in GitHub Desktop.
Print any lua value as a readable string
---Inspect a value
---
---Converts nil, boolean, number, string or table to string
---Any other type is converted with `tostring`.
---
---List-like tables are printed without their indices
---
---Usage:
---
---```lua
---print(1, Inspect(nil))
---print(2, Inspect(true))
---print(3, Inspect(27.9))
---print(4, Inspect("hello world"))
---print(5, Inspect("hello\n\tworld"))
---print(6, Inspect({ 1, "2", 3 }))
---print(7, Inspect({ [{ a = 1, b = 4 }] = { 1, 2, 3 }, x = false, [4] = { x = 1, y = 2, ["a\tb"] = 3 } }))
---```
---
---Output:
---```
---1 nil
---2 true
---3 27.9
---4 "hello world"
---5 "hello\n\tworld"
---6 [1, "2", 3]
---7 {
--- x = false,
--- [4] = {
--- x = 1,
--- y = 2,
--- ["a\tb"] = 3,
--- },
--- [{
--- b = 4,
--- a = 1,
--- }] = [1, 2, 3],
---}
---```
---@param v any
---@param indent nil
---@return string
function Inspect(v, indent)
if indent == nil then indent = 0 end
local function is_list(tbl)
local prev = 0
for key, value in pairs(tbl) do
prev = prev + 1
if key ~= prev then return false end
end
return true
end
---@param str string
---@return string
---@return boolean
local function escape(str)
local escape_chars = {
["\n"] = "\\n",
["\t"] = "\\t",
["\\"] = "\\\\",
["\""] = "\\\"",
["\'"] = "\\\'",
}
local out = str:gsub(".", function(char) return escape_chars[char] or char end)
return out, out ~= str
end
if type(v) == "nil" then return "nil" end
if type(v) == "string" then return '"' .. escape(v) .. '"' end
if type(v) == "table" then
if is_list(v) then
if rawequal(next(v), nil) then return "{}" end
local outstr = ""
outstr = '[' .. Inspect(v[1], indent)
for i = 2, #v do
outstr = outstr .. ", " .. Inspect(v[i], indent)
end
return outstr .. ']'
else
local outstr = ""
outstr = '{\n'
for key, value in pairs(v) do
local keystr = (function()
if type(key) == "string" then
local _, escaped = escape(key)
if not escaped then return key end
end
return "[" .. Inspect(key, indent + 1) .. "]"
end)()
outstr = outstr ..
string.rep(" ", indent + 1) .. keystr .. " = " .. Inspect(value, indent + 1) .. ",\n"
end
return outstr .. string.rep(" ", indent) .. '}'
end
end
return tostring(v)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment