🎓 A1Learner
🔍
0 of 49 lessons completed

Lua Close Order

Close order is the order in which Lua closes to-be-closed variables. Lua closes them in reverse order of creation, last created first.

Several variables close in reverse order

Three variables close in the opposite order from creation.

local log = {}
local function mk(name)
  return setmetatable({name = name}, {__close = function(v) log[#log + 1] = v.name end})
end
do
  local a <close> = mk("first")
  local b <close> = mk("second")
  local c <close> = mk("third")
end
print(table.concat(log, ","))

A nested scope closes before the outer scope continues

The inner scope closes before the outer scope prints again.

local log = {}
local function mk(name)
  return setmetatable({name = name}, {__close = function(v) log[#log + 1] = v.name end})
end
do
  local a <close> = mk("outer")
  do
    local b <close> = mk("inner")
  end
  print(table.concat(log, ","))
end
print(table.concat(log, ","))

A return still closes the variables first

The return closes both variables before the caller prints the log.

local log = {}
local function mk(name)
  return setmetatable({name = name}, {__close = function(v) log[#log + 1] = v.name end})
end
local function work()
  local a <close> = mk("one")
  local b <close> = mk("two")
  return "done"
end
print(work())
print(table.concat(log, ","))

Example

local log = {}
local function mk(name)
  return setmetatable({name = name}, {__close = function(v) log[#log + 1] = v.name end})
end
do
  local a <close> = mk("a")
  local b <close> = mk("b")
  do
    local c <close> = mk("c")
    local d <close> = mk("d")
  end
  print(table.concat(log, ","))
end
print(table.concat(log, ","))

Key points

  • Reverse order: the last <close> variable created is the first one closed.
  • Nested scope: a nested scope closes its variables before the outer scope continues.
  • Return exit: a return still closes the variables before the caller continues.
  • Break exit: a break out of a loop still closes the variables of that round.
  • Loop round: each round of a loop closes its variables before the next round starts.

In this example, the outer scope opens a and b, then the inner scope opens c and d. The inner scope ends first and closes d then c. The outer scope ends last and closes b then a.

Note

the order matches a stack, last in first out.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Three <close> variables are created in the order red, green, blue. Which one closes first?