🎓 A1Learner
🔍
0 of 49 lessons completed

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?