--- -- Strict declared global library. Checks for undeclared global variables -- during runtime execution. -- -- This module places the strict function in the global -- environment. The strict function allows a script to add runtime checking so -- that undeclared globals cause an error to be raised. This is useful for -- finding accidental use of globals when local was intended. -- -- A global variable is considered "declared" if the script makes an assignment -- to the global name (even nil) in the file scope. -- -- @class module -- @name strict -- @copyright Copyright© Same as Nmap--See http://nmap.org/book/man-legal.html local error = error; local getfenv = getfenv; local lmodule = module; local rawset = rawset; local rawget = rawget; local setfenv = setfenv; local type = type; local getinfo = debug.getinfo; local function what () local d = getinfo(3, "S"); return d and d.what or "C"; end --- The strict function. -- -- This function adds runtime checking to the global environment for use of -- undeclared globals. A global is 'undeclared' if not assigned in the file -- (script) scope previously. An error will be raised on use of an undeclared -- global. function strict () local _G = getfenv(2); local mt = getmetatable(_G) or setmetatable(_G, {}) and getmetatable(_G); local _newindex, _index = mt.__newindex, mt.__index; mt.__declared = {}; function mt.__newindex (t, n, v) if type(_newindex) == "function" then _newindex(t, n, v); -- hook it end if not mt.__declared[n] then local w = what(); if w ~= "main" and w ~= "C" then error("assign to undeclared variable '"..n.."'", 2); end mt.__declared[n] = true; end rawset(t, n, v); end function mt.__index (t, n) if type(_index) == "function" then local v = _index(t, n); -- hook it if v ~= nil then return v end elseif _index ~= nil then local v = _index[n]; if v ~= nil then return v end end if not mt.__declared[n] and what() ~= "C" then error("variable '"..n.."' is not declared", 2); end return rawget(t, n); end end local strict = strict; function module (...) local myenv = getfenv(1); lmodule(...); strict(); setfenv(2, getfenv(1)); setfenv(1, myenv); end return strict;