Lua Debug Upvalues
Debug upvalues are the captured values a function carries with it. The debug library can read them and change them.
Read the first captured value
The counter function captured one value. Read it by position 1.
local function makeCounter()
local count = 10
return function()
count = count + 1
return count
end
end
local countUp = makeCounter()
local name, value = debug.getupvalue(countUp, 1)
print(name)
print(value)
print(countUp())Change the captured value
Set the first captured value to 100. The next two calls count up from there.
local function makeCounter()
local count = 10
return function()
count = count + 1
return count
end
end
local countUp = makeCounter()
debug.setupvalue(countUp, 1, 100)
print(countUp())
print(countUp())A position past the end gives nil
This function captured only one value. Position 2 has nothing to read.
local function makeCounter()
local count = 10
return function()
count = count + 1
return count
end
end
local countUp = makeCounter()
local name, value = debug.getupvalue(countUp, 2)
print(name)
print(value)
print(countUp())Example
local function makeAdder()
local total = 0
local step = 5
return function()
total = total + step
return total
end
end
local addStep = makeAdder()
print(addStep())
local name, value = debug.getupvalue(addStep, 2)
print(name)
print(value)
debug.setupvalue(addStep, 2, 10)
print(addStep())Key points
- A captured value is a variable a function took from its surrounding code.
- Use debug.getupvalue to read one captured value by its position.
- The call returns the name first and the value second.
- Use debug.setupvalue to set one captured value by its position.
- Changing a captured value changes what the function does next.
In this example, the adder captured total first and step second. The first call adds 5 to 0 and gives 5. Reading position 2 shows the name step and the value 5. Setting step to 10 makes the next call add 10 to 5 and give 15.
Note
A position past the last captured value gives nil for both name and value.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does debug.setupvalue(f, 1, 100) do?