PcoWSkbVqDnWTu_dm2ix
We use cookies on this site to enhance your user experience

Jul 03 2018, 10:06 AM PST 5 min

Scope is a block of code in which variables are declared and accessible. Code blocks like for-loops, while-loops, repeat until-loops, functions, if-then statements, and do-end chunks all create a new variable scope. Variables created within a contained scope are discarded and “forgotten” (a.k.a. “garbage collected”) when the scope is exited.

Variables can be declared in two ways: locally (with the local keyword), and globally. Global variables are always in scope: no matter where you declare them, they are always accessible. All variables default to the global scope unless they are explicitly placed in the local scope using the local keyword.

Global variables are only global within the content of the associated script. In other words, a script is not able to access the global variables contained by another script. If you need the ability to do that, register your variables in the _G table - a shared data construct accessible to all scripts.

Let’s take a look at some examples.

When myFunction was called, myVariable was set to 64. Since this variable is globally scoped, it could be accessed outside the function. This is why the output was “myVariable is 64”. Take a look at this example using the local keyword to change the scope of a variable.

That was outputted because myVariable was confined to myFunction’s environment or its scope. Therefore, it was not able to access the value outside of that function.

Do Block

A do end block creates a new scope. This can be useful to create a new block of local variables, without overriding the non-local variables. If you have a long script with a lot of variables, this can be useful. Remember that you can also create local functions using this.

Notice here that the “Pear” variable isn’t changed to its “original” non-local value, because we didn’t use the local statement in the do block.

Lexical Scoping

In the last example you may have noticed that I said “the variable was also accessible by descendant environments”. This concept is called lexical scoping.

if true then --level 1
	local a = 82.5
	if true then --level 2
		local b = 64
	end
end

This is a simple example with two conditionals. If you recall, conditionals also have their own environment. Here is a snippet to prove this:

if true then --level 1
	local a = 82.5
	if true then --level 2
		local b = 64
	end
	print(b) --> nil
end

Its nil because variable b was confined to the scope of the second conditional. Lexical scoping will allow one to do this:

if true then --level 1
	local a = 82.5
	if true then --level 2
		print(a) --> 82.5
		local b = 64
	end
end

Even though the second conditional has its own environment, because of lexical scoping, a was inherited. Variables that are lexically scoped are called upvalues.

Using the “local” statement

You can also define a local variable in a scope without assigning any value to it, but making it possible to read that variable on the current “scope level”. You can do this by using the “local” keyword and then the variable name behind it. An example:

function whereIsHi(t)
    local foundAt
    for key, value in pairs(t) do
        if value == "Hi" then
            foundAt = key
        end
    end
    return foundAt
end

This code would return nil if the table “t” does not have a table “Hi” in it, and otherwise will return the last index found which contains the “Hi” value.

Were local foundAt not used, then foundAt would be globally scoped, making it accessible elsewhere, and making whereIsHi overwrite any variables with the name foundAt from outer scopes.

See Also

Tags:
  • basics