Sends a log message if any nil
global variables are set or read by any module involved in the current module invocation. A less drastic version of the strict
library, which triggers an error in the same situation.
This module logs uses of nil
global variables in code that is executed after the module is loaded. There is no deduplication so the same message can appear many times if it is triggered by more than one template.
After the name of the variable and whether it was set or accessed, a backtrace is shown. The first line of the backtrace gives the line of the module where a global variable was used, which is often the line that needs to be changed. Sometimes a global variable is used because of a misspelling; sometimes a variable is defined and local
needs to be added to its definition (which requires refactoring or forward declaration if the variable is used before it is defined).
To use it, add require("Module:log globals")
temporarily at the top of the module. Preview a page by entering a page in the "Preview page with this template" box and pressing the "Show preview" button. Click to open the "Parser profiling data:" box at the bottom of the page, if it is not open already, and click the "Expand" button next to the "Lua logs" label. Inside is a log of global variables that were accessed or set in any code that was executed after this module was loaded. This includes global variables in code in other modules. After changing the global variables to local, and before saving the module, remove require("Module:log globals")
.
local mt = getmetatable(_G) or {}
local function print(val)
if type(val) == "table" then
local printout = {}
local i = 1
for k, v in pairs(val) do
table.insert(printout, (" = %s"):format(tostring(k), tostring(v)) )
i = i + 1
if i > 5 then
table.insert(printout, "...")
break
end
end
printout = { table.concat(printout, ", ") }
table.insert(printout, 1, "{")
table.insert(printout, "}")
return table.concat(printout)
elseif type(val) == "string" then
return '"' .. val .. '"'
else
return tostring(val)
end
end
mt.__newindex = function (self, key, value)
if key ~= "arg" then
mw.log("Global variable " .. print(key) .. " was set to "
.. print(value) .. " somewhere:",
debug.traceback("", 2))
end
return rawset(self, key, value)
end
mt.__index = function (self, key)
if key ~= "arg" then
mw.log("Nil global variable " .. print(key) .. " was read somewhere:",
debug.traceback("", 2))
end
return rawget(self, key)
end
setmetatable(_G, mt)