Lua Functions
Function Basics
Definition and calling
-- Named function
local function greet(name)
return "Hello, " .. name
end
-- Anonymous function assigned to variable
local square = function(x) return x * x end
-- Multiple return values
local function parse_endpoint(endpoint)
local host, port = endpoint:match("(.+):(%d+)")
return host, tonumber(port)
end
local host, port = parse_endpoint("10.50.1.40:8200")
print(host, port) -- 10.50.1.40 8200
-- Discard return values
local _, port_only = parse_endpoint("10.50.1.40:8200")
Variadic Functions
Variable arguments with …
-- Variadic function
local function log(level, ...)
local args = { ... }
local msg = table.concat(args, " ")
print(string.format("[%s] %s", level, msg))
end
log("INFO", "Server", "started", "on", "port", "8080")
-- [INFO] Server started on port 8080
-- select() with varargs
local function count_args(...)
return select("#", ...) -- number of args (including nil)
end
local function first_arg(...)
return (select(1, ...)) -- first arg
end
Closures
Functions capture enclosing scope
local function make_counter(start)
local count = start or 0
return {
increment = function()
count = count + 1
return count
end,
get = function()
return count
end,
}
end
local c = make_counter(10)
print(c.increment()) -- 11
print(c.increment()) -- 12
print(c.get()) -- 12
-- Iterator factory
local function range(start, stop, step)
step = step or 1
local i = start - step
return function()
i = i + step
if i <= stop then return i end
end
end
for n in range(1, 5) do
print(n) -- 1, 2, 3, 4, 5
end
Higher-Order Functions
Functions as arguments and return values
-- Map
local function map(t, fn)
local result = {}
for i, v in ipairs(t) do
result[i] = fn(v)
end
return result
end
local ports = { 22, 80, 443 }
local labels = map(ports, function(p)
return string.format("%d/tcp", p)
end)
-- { "22/tcp", "80/tcp", "443/tcp" }
-- Compose
local function compose(f, g)
return function(...)
return f(g(...))
end
end
local double = function(x) return x * 2 end
local add_one = function(x) return x + 1 end
local double_then_add = compose(add_one, double)
print(double_then_add(5)) -- 11
-- Memoize
local function memoize(fn)
local cache = {}
return function(arg)
if cache[arg] == nil then
cache[arg] = fn(arg)
end
return cache[arg]
end
end
Method Syntax
Colon syntax and self
-- Dot syntax (explicit self)
local device = { hostname = "vault-01" }
function device.info(self)
return self.hostname
end
-- Colon syntax (implicit self) -- preferred
function device:status()
return self.hostname .. " is up"
end
-- Calling
print(device.info(device)) -- explicit
print(device:status()) -- implicit self (same as device.status(device))