Nanfeng

Notes on software development, code, and curious ideas

Local Variables and Blocks in Lua

Lua locals have lexical scope: a name is visible from its declaration to the end of the innermost enclosing block. Function bodies, branches, loops, and explicit do ... end regions are blocks.

1
2
3
4
5
6
local outer = "visible"
do
local inner = "temporary"
print(outer, inner)
end
-- inner is no longer visible

Declare values close to their first use. Locals avoid accidental global state and are generally faster to access than globals.

Declaration timing

A local is not in scope inside its own initializer:

1
local value = value -- right-hand value refers to an outer/global name

This matters for recursive local functions. Use the dedicated syntax:

1
2
3
4
local function factorial(n)
if n == 0 then return 1 end
return n * factorial(n - 1)
end

It is equivalent to declaring the local first and assigning the function afterward.

Multiple assignment

1
2
local x, y = 10, 20
x, y = y, x

Lua evaluates right-hand expressions before assignment, which makes swaps safe. Missing values become nil, and extra values are discarded, subject to Lua’s multiple-return adjustment rules.

Shadowing and lifetime

An inner declaration may shadow an outer name:

1
2
3
4
5
local status = "outer"
if ready then
local status = "inner"
print(status)
end

Use shadowing sparingly because identical names can make reviews confusing. A local normally becomes collectible after its block and all closures capturing it are gone. Scope is therefore both a naming rule and part of object lifetime.

+