Topic 07-variable-scope.md
Scope of Variables
Globals
There are two kinds of variables in Lua, local and global. Globals are visible throughout the whole program, The standard functions in Lua are mostly contained in global tables, like math and table . An assignment like this:
newGlobal = 'hello'
causes newGlobal
to be publically available – it is not just visible in the declared file.
Global variables are contained in the global table. The variable _G
refers to this
table explicitly, so _G.print
works as expected. But otherwise there is nothing special
about _G
and setting it to some other value has no effect on program operation.
To understand global functions you need to remember how tables and functions work. It is easy to change the behavior of the whole program by redefining a global:
function print(x) io.write(tostring(x),'\n') end
This is totally equivalent to the following table key assignment:
_G["print"] = function(x) ... end
So you will not be surprised when this causes unexpected behavior – suddenly every call to print works differently (since the new version only takes one argument.) Sometimes this technique is useful and it has a name: “monkey patching”. But generally it is a disaster waiting to happen, because it messes with people’s expectations of how a standard function works.
Lua cannot tell you that a function is undefined at compile-time. If you misspell a name
newGlbal
then it will just tell you that you have tried to call a nil
value, because
_G["newGlbal"]
is nil
.
Locals
Local variables, on the other hand, are only visible in the block where they have been declared.
There are two places where local variables are implicitly declared; the first is the
argument list of a function, and the second is the variables defined by a for
statement. In this function, x
,y
and z
are local because they are arguments,
and k
,v
are locals because they are for
variables.
function fun(x,y,z) for k,v in pairs(x) do .... end -- B2 print(k) end -- B1
Local variables always have a ‘scope’, which is the the part of the program where
they are valid and visible. In this function, x
is visible up to the end of block
B1 and k
is visible up to the end of block B2. In particular, k
is not visible in
print(k)
!
If a variable is cannot be found, then Lua assumes it is global, with a nil
value.
The problem then is that a misspelling is not an error , just nil
!
Locals may be explicitly defined using the local
keyword. This function makes a
‘shallow copy’ of a table by creating a new table and copying the key/value pairs:
function copy (t) local res = {} for k,v in pairs(t) do res[k] = v end return res end
local
is the correct way to do this, because then the variable res
is not visible
outside the function. The function is then pure, i.e. it has no global side-effects.
Local declarations can ‘nest’ inside each other. Inside the for-loop, k
has a different
meaning to k
outside the loop.
function dumpv( t ) local k = 1 for k.v in pairs(t) do print(k,v) end print('hello',k) --> hello 1 ! end
Good programming practice is to make everything as local as possible. As a bonus, accessing locals is significantly faster than accessing globals. Each global access involves a table lookup, whereas locals define ‘slots’ which are much more efficient.