Skip to content

Instantly share code, notes, and snippets.

@eliasdaler
Last active February 27, 2023 18:15
Show Gist options
  • Save eliasdaler/588f7183e6db485979cc874ced52566c to your computer and use it in GitHub Desktop.
Save eliasdaler/588f7183e6db485979cc874ced52566c to your computer and use it in GitHub Desktop.
string.format is cool, but we can do better
-- depends on https://github.com/kikito/inspect.lua
local inspect = require 'inspect'
local M = {}
local function tostring_impl(v)
if type(v) == "table" then
-- change to inspect(v, {newline=""}) if you want to print everything tables on one line
return inspect(v)
elseif type(v) == "nil" then
return "<nil>"
end
return tostring(v)
end
local function fmt_n(s, t)
return (s:gsub('({[_%a][_%w]*})', function(w)
local v = t[w:sub(2, -2)]
return tostring_impl(v)
end))
end
function M.fmt(s, ...)
if ... == nil then -- allows to call it like this: fmt.fmt(val)
return M.fmt("{}", s)
end
if type(...) == "table" and
not string.find(s, "{}") then
-- using named placeholders, otherwise can be fmt({}, t)
return fmt_n(s, ...)
end
local t = { ... }
local c = 0
return (s:gsub('({})', function()
c = c + 1
local v = t[c]
return tostring_impl(v)
end))
end
function M.print(...)
print(M.fmt(...))
end
return M
local fmt = require 'fmt'
local line = 32
fmt.print("[WARNING] (line: {}, script: '{}', data: {}): {} = {}",
line, "game.lua", "fmt",
"foo", { bar=42, nice="OK!"}
)
local line = 39
fmt.print("[INFO] (line: {line}, script: '{script}', data: {data}): {foo} = {foo_cont}",
{
line = line,
script = "game.lua",
data = nil,
foo = "foo",
foo_cont = { bar=1, nice="wow"}
}
)
[WARNING] (line: 32, script: 'game.lua', data: fmt): foo = {
bar = 42,
nice = "OK!"
}
[INFO] (line: 39, script: 'game.lua', data: <nil>): foo = {
bar = 1,
nice = "wow"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment