Module:superstrict

To use this module, simply add require("Module:superstrict") to another module. It returns no values.

Superstrict works similarly to the standard strict library, which throws an error if an attempt is made to access an undeclared global variable or to declare a new one. Superstrict adds an additional restriction by also throwing an error if any global variable is accessed, even if it has already been declared. This includes all of the standard global variables and functions.

The purpose of this is to make it easier to optimize functions which need to be as fast as possible, which can be improved by minimizing the number of times global variables are accessed. The usual way to do this is to declare any relevant global variables as local variables with the same name, which must be done before this module is called.

Superstrict should only be used for debugging purposes and should not be used in live code, since it negatively impacts performance when enabled, and significantly increases the risk that an innocuous edit will cause unexpected errors in other modules.


local dump = mw.dumpObject
local error = error

local new_G = {}
new_G.__index = new_G
setmetatable(_G, new_G)

for k, v in next, _G do
	new_G[k] = v
	_G[k] = nil
end

function new_G:__index(k)
	-- `arg` and `_G` are used by `require`.
	if k == "arg" or k == "_G" then
		return new_G[k]
	elseif new_G[k] then
		error("variable " .. dump(k) .. " is a global", 2)
	end
	error("variable " .. dump(k) .. " is not declared", 2)
end

function new_G:__newindex(k, v)
	if k ~= "arg" then
		error("assign to undeclared variable " .. dump(k), 2)
	end
	new_G[k] = v
end