Scope

(Redirected from Environment)

What is Scope?[edit]

Scope is a block of code in which variables are declared. for loops, while loops, repeat until loops, functions, if then, and do end chunks all create a new variable scope.

Variables can be declared in two ways: local (with the local keyword), and global. Global variables are always in scope: no matter where you declare them, they are always accessible.

function myFunction()
	myVariable = 64 --globally scoped
end
 
myFunction()
 
print("myVariable is " .. myVariable)
myVariable is 64

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.

function myFunction()
	local myVariable = 64
end
 
myFunction()
print("myVariable is " .. myVariable)
myVariable is nil

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[edit]

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.

local Apple = 10
local Pear = 5
do
	local Apple = Apple - 5
	Pear = Pear - 2
	print(Apple, Pear)
end
print(Apple, Pear)
5	3 
10	3

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[edit]

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[edit]

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[edit]