Lua Cheatsheet
Modules, Errors, and IO
Use this Lua reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Module Pattern
File mathbox.lua:
local M = {} function M.double(n) return n * 2 end function M.square(n) return n * n end return M
Use it:
local mathbox = require("mathbox") print(mathbox.double(7))
require caches modules by name. The module file normally returns a table.
package.path
Lua searches module names through package.path templates.
print(package.path) package.path = package.path .. ";./lib/?.lua"
A module name like tools.text maps through templates such as tools/text.lua.
error and assert
if not user then error("missing user") -- prefixes "file:line:" where error() ran end local function set_port(n) if type(n) ~= "number" then error("port must be a number", 2) -- level 2: blame the caller's line end end error({code = 404}) -- any value can be thrown; non-strings -- get no position prefix local n = assert(tonumber(text), "expected a number")
error(msg, level): level 1 (default) points at where error was called, level 2 at the function's caller, 0 adds no position. assert(x, msg) returns x (and any extra values) when truthy; otherwise it raises msg.
pcall
local ok, result = pcall(function() return risky() end) if ok then print(result) else print("failed: " .. tostring(result)) end
pcall returns true, ...results on success and false, error_object on failure.
xpcall and Tracebacks
pcall unwinds the stack before returning, so the traceback is already gone. xpcall runs a message handler at the point of the error:
local ok, err = xpcall(risky, debug.traceback) if not ok then io.stderr:write(err, "\n") end -- extra arguments after the handler are passed to the function (5.2+) local ok, result = xpcall(parse, debug.traceback, text)
debug.traceback appends the stack trace to the error message — the standard way to get useful crash logs.
Reading Input
local line = io.read("l") -- one line, without the newline ("L" keeps it) local all = io.read("a") -- rest of input local n = io.read("n") -- next number
Since Lua 5.3 the formats are plain "l", "a", "n"; the legacy "*l"/"*a"/"*n" spellings still work everywhere and are required on Lua 5.1/LuaJIT. io.read("n") leaves the newline behind. For mixed line and number reading, many scripts read lines and use tonumber.
Writing Output
print("line") -- adds newline and tabs between args io.write("no newline") io.write("value\n")
Use io.write when exact spacing matters.
Files
local f = assert(io.open("data.txt", "r")) local text = f:read("a") f:close() local out = assert(io.open("out.txt", "w")) out:write("hello\n") out:close()
Modes: "r", "w", "a", plus binary variants like "rb" and "wb".
Useful Standard Libraries
| Library | Common use |
|---|---|
math | floor, ceil, sqrt, random, min, max |
string | text operations and patterns |
table | insert, remove, sort, concat |
io | stdin, stdout, files |
os | time, date, environment, execute |
debug | introspection; avoid in normal app code |
math.max(3, 9, 2) os.getenv("HOME") os.date("%Y-%m-%d")