-- protect the current environment so that accessing undefined variables raises an error -- cache all globals so that the metamethods don't recursively trigger themselves local getinfo = debug.getinfo local rawget = rawget local _G = _G local mt = getmetatable(_ENV) if mt == nil then mt = {} setmetatable(_ENV, mt) end local function what() local d = getinfo(3, "S") return d and d.what or "C" end mt.__newindex = function(t, key, value) -- allow native code to set values to the environment, otherwise we cannot load anything if what() ~= "C" then error("attempt to set undefined global variable '" .. tostring(key) .. "'", 2) end rawset(t, key, value) end mt.__index = function(t, key) -- reading undefined value from _ENV goes through to _G local value = rawget(_G, key) if value then return value end error("undefined global variable '" .. tostring(key) .. "'", 2) end