icecream.lua
, a port of the debugging utility IceCream,
enhances print debugging by providing more informative and visually appealing output.
Use ic()
just like you would use print()
for debugging:
local ic = require("icecream")
local foo = function()
local x = 42
ic("bar", x, math.abs(-9), {
greetings = "hello",
__call = function(self)
print(self.greetings)
end,
})
end
foo()
Output:
luarocks install luamark
icecream.lua
is a single file that can be easily integrated into your project.
Download icecream.lua and include it in your project directory.
Ensure that optional dependencies are available for extra features:
- dumbParser: Introspecting expressions and variable names. e.g:
ic| x = 42
- ansicolors: Enabling colored output.
- inspect: Pretty-printing tables.
- luasystem: Terminal width detection and consistent environment variable reading on Windows.
-
Import IceCream:
local ic = require("icecream")
Assign the result of require to a variable named ic
to increase robustness when introspecting.
-
Debugging with
ic()
:Use
ic()
as you would useprint()
for debugging:local ic = require("icecream") local foo = function() local x = -42 ic(math.abs(x)) end foo() -- Output: ic| readme.lua:5 <foo>: math.abs(x) = 42
- Output format:
-
Inspection:
ic()
inspects itself and prints both its arguments and their values. -
Context: Each output includes the file, line number, and function.
-
Color: The output features highlighting.
-
Multi-lines:: The output wraps on new lines as needed.
-
Stack traceback: Without arguments,
ic()
prints the stack traceback.
local ic = require("icecream")
local function foo()
ic()
end
foo()
-- Output:
-- ic| readme.lua:4 <foo>:
-- stack traceback:
-- readme.lua:4: in function 'foo'
-- readme.lua:7: in main chunk
-- [C]: ?
IceCream supports StackTracePlus
.
With StackTracePlus, the previous snippet outputs:
ic| readme.lua:4 <foo>
Stack Traceback
===============
(3) Lua local 'foo' at file 'readme.lua:4'
Local variables:
x = number: 1
y = number: 2
(4) main chunk of file 'readme.lua' at line 7
(5) C function 'function: 0x600001aec0c0'
ic()
returns its arguments, so you can easily insert it into pre-existing code.
local ic = require("icecream")
local x, y = ic(1, 2)
assert(x == 1)
assert(y == 2)
local t = { "hello" }
assert(t == ic(t))
IceCream allows customization of its output behavior:
ic.color = false -- Disable colorized output.
ic.max_width = 100 -- Wrap text if longer than 100 characters.
ic.indent = " " -- Indent with 4 spaces.
ic.prefix = "DEBUG" -- Change the prefix from 'ic|' to 'DEBUG'.
ic.include_context = false -- Disable file name, line number, and function name output.
ic.traceback = function() end -- Custom traceback function (can be nil), defaults to debug.traceback.
ic.output_function = function() end -- Custom output function, e.g., write to a file.
When the following environment variables are present and not empty strings:
NO_COLOR
: Prevents ANSI color when present.NO_ICECREAM
: Disables ic outputs permanently if not an empty string
To make ic()
available globally, without require, use the ic:export()
method.
The LUA_INIT
environment variable allows invocation of
ic:export()
when Lua starts, ensuring global availability of ic
.
For example, add this to your .bashrc
:
export LUA_INIT="local ok, ic = pcall(require, 'icecream'); if ok and ic.export then ic:export() end"
Activate or deactivate debugging output dynamically with ic.enable()
and ic.disable()
. Set the environment variable NO_ICECREAM
to disable outputs permanently.
ic:format()
works like ic() but returns a string instead of printing the output.
IceCream relies on debug.getinfo
, which provides partial information about function calls, resulting in some limitations:
-
Naming Convention: Assign the result of require to a variable named ic for robustness. While not mandatory,
ic
might not detect nested calls otherwise.local dbg = require("icecream") dbg.include_context = false -- ic| { hello = "world" } dbg({ hello = "world" }) -- ic| dbg({hello="world"}) = { hello = "world" } tostring(dbg({ hello = "world" }))
-
Single Call Limitation:
ic
only supports oneic:format()
oric()
per line of code.local ic = require("icecream") assert(ic(1) == ic(2, 3))-- Error: Failed to parse arguments from source
-
Return Value Restriction: In Lua 5.1,
ic:format()
oric()
can't be directly used as return values from functions.local ic = require("icecream") local function greetings(name) return ic("hello", name) end local hello, name = greetings("Jeff") -- Error: Cannot use IceCream as a return value
icecream.lua
has the MIT License. See LICENSE for more information.