I found this nifty code example on the Lua mailing list. It was written by Roberto Ierusalimschy, the developer of Lua.
What this does is use a metatable on the global (_G) table to make sure that setting variables, or reading them, is only done to "declared" variables. That is, variables that are explicitly mentioned on the global script space.
This helps prevent common errors like misspelling variable names in functions, or accidentally assigning to a global variable when a local one would be more sensible.
Let's assume you save that to disk as "strict.lua".
Some example code:
A sensible strategy in these cases would be to put "local" in front of variables and functions that are really supposed to only exist inside the scope of the local function.
--
-- strict.lua
-- checks uses of undeclared global variables
-- All global variables must be 'declared' through a regular assignment
-- (even assigning nil will do) in a main chunk before being used
-- anywhere or assigned to inside a function.
--
local mt = getmetatable(_G)
if mt == nil then
mt = {}
setmetatable(_G, mt)
end
mt.__declared = {}
mt.__newindex = function (t, n, v)
if not mt.__declared[n] then
local w = debug.getinfo(2, "S").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
mt.__index = function (t, n)
if not mt.__declared[n] then
error("variable '"..n.."' is not declared", 2)
end
return rawget(t, n)
end
What this does is use a metatable on the global (_G) table to make sure that setting variables, or reading them, is only done to "declared" variables. That is, variables that are explicitly mentioned on the global script space.
This helps prevent common errors like misspelling variable names in functions, or accidentally assigning to a global variable when a local one would be more sensible.
Let's assume you save that to disk as "strict.lua".
Some example code:
require "strict"
function f ()
a = 2 --> error: assign to undeclared variable 'a'
print (b) --> error: variable 'b' is not declared
function g () --> error: assign to undeclared variable 'g'
end -- g
end -- f
f ()
A sensible strategy in these cases would be to put "local" in front of variables and functions that are really supposed to only exist inside the scope of the local function.