Lua Scoping

lua-users home

The following pages in the reference manual describe Lua's scoping rules:

Some pages concerning Lua variable scoping:

Older Historical Notes on Lua 4.0 Scoping Rules (IGNORE THIS PART FOR MORE RECENT LUAS)

This page will describe Lua's scoping rules. Furthermore it will attempt to do so without using the terms "static scoping" and "lexical scoping" whose meaning can vary depending on the person or text (see LuaScopingDiscussion).


In Lua there are local and global scopes. Variables default to global scope unless they have the local qualifier.

The binding of variable names is, to use a taboo word, static. This is a useful property because it means you can always determine what variable a given name is bound to from the source code. In contrast, in a language with dynamic binding, this may depend on context.

Scopes are created naturally by functions, control constructs (for, if, etc.), and chunks. A scope can also be created explicitly using do...end.

Function scope limitation

Function scopes have a special limitation in that outer scopes (other than the global scope) may not be accessed. This applies to any function, but is most noticable in the case of nested functions where you may want to access locals of the enclosing scope.


Upvalues were added to work around the function scope limitation. Prefixing an outer-scope variable reference with % produces a copy of that variable as of the function's instantiation. Only the immediate scope containing the function and the global scope may be accessed in this manner.

Since the variable is a copy, it's not possible for the function to alter the original value. A common solution to this problem is to put such variables inside a table and access the table as an upvalue. The table acts as a function closure.

local closure = { a=5 }
local foo = function()
    %closure.a = %closure.a + 1
    %closure.b = 'hello'

Someone may tell you that upvalues are a feature of Lua, but don't believe it.

Special access to scope contents

The global scope can be accessed as a table from Lua using the function globals. The local scope can also be accessed using debugging interfaces.
RecentChanges · preferences
edit · history
Last edited June 23, 2016 3:37 pm GMT (diff)