Exercise on Closures
Trace the following code in a debugger
- 1. Determine how name and ages are used in each function
- 2. Discuss and explain to the group
local names = {'Carol', 'Jess', 'John', 'Daniel' }
local ages = {Carol = 20, Jess = 14, John = 41, Daniel = 63}
table.sort(names, function (name1, name2)
return ages[name1] > ages[name2] -- ages is an upvalue here, can be seen
end)
for i = 1, #names do
print(names[i])
end
names = {'Barbara', 'Ben', 'Harry', 'Jen' }
ages = {Barbara = 20, Ben = 14, Harry = 41, Jen = 63}
function sortByAge (names, ages) -- references names and ages are local to sort
table.sort(names,function (name1, name2) -- names and ages can be seen within sort
return ages[name1] > ages[name2] -- ages can be seen within anonymous function
end)
end
sortByAge(names, ages)
print("\n\n\n")
for i = 1, #names do
print(names[i])
end
names = {'Barbara', 'Ben', 'Harry', 'Jen' }
ages = {Barbara = 20, Ben = 14, Harry = 41, Jen = 63}
function sortByAge () -- call has two parameters neither of which are used
function ageCompare(name1, name2) -- ages and names are upvalues here
return ages[name1] > ages[name2] -- ages can be seen within ageCompare
end
table.sort(names,ageCompare) -- references names and ages can be seen within sortByAge
end
sortByAge(names, ages) -- passed in names and ages in the call but they are not used
print("\n\n\n")
for i = 1, #names do
print(names[i])
end
```
* In the examples the ages variable within the function is called a non-local variable
* It is not global and it is not local
* This is sometimes referred to as an upvalue
* It can be seen because of the scoping rules of Lua
_Closure definition_ - A closure is a function plus all that it needs to access non-local variables correctly
Trace through the following code using the debugger
* 1\. Determine how the closures work
* 2\. Explain and discuss
function counter ()
local i = 0;
return function ()
i = i + 1
return i
end
end
theCounter = counter()
print(theCounter()) -- the function reference continues to refer to the same function
print(theCounter()) -- and its local variables (including its parameters)
-- iterators and closure
function iterator(theList)
local i = 0
return (function () i = i + 1; return theList[i] end)
end
local numbers = {"Earth","Mars","Saturn","Venus"}
iter = iterator(numbers) -- get a reference to the function
while true do
local theItem = iter() -- use the function
if theItem == nil then break end
print (theItem)
end
```
</pre>