Variable Attributes: const and close

<close> values must have a __close metamethod (or be nil/false). <close> variables are also const.

-- <const> (5.4): compile-time constant locals (can't be reassigned)
local PI <const> = 3.14159
local MAX_PLAYERS <const> = 8
-- PI = 3         --> compile error: attempt to assign to const variable 'PI'

-- <close> (5.4): to-be-closed variables; __close runs when the variable goes out of scope (even on error)
local function open_file(path, mode)
    local f = assert(io.open(path, mode))
    return setmetatable({file = f}, {
        __close = function(self, err)
            print("closing " .. path .. (err and (" due to error: " .. tostring(err)) or ""))
            self.file:close()
        end,
        __index = function(self, k) return function(_, ...) return self.file[k](self.file, ...) end end,
    })
end

do
    local f <close> = open_file("out.txt", "w")
    f:write("hello\n")
end                               --> "closing out.txt" runs here automatically

-- File handles already have __close in 5.4:
do
    local fh <close> = assert(io.open("out.txt"))
    print(fh:read("l"))
end

-- Generic for loops close the 4th value (closing value) when the loop ends, even via break