/usr/share/lua/5.1/pl/strict.lua is in lua-penlight 1.2.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | --- 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. Existing metatables' __newindex and __index
-- metamethods are respected.
--
-- You can set any table to have strict behaviour using `strict.module`
--
-- @module pl.strict
require 'debug' -- for Lua 5.2
local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget
local strict = {}
local function what ()
local d = getinfo(3, "S")
return d and d.what or "C"
end
--- make an existing table strict.
-- @param name name of table (optional)
-- @param mod table - if `nil` then we'll return a new table
-- @param predeclared - table of variables that are to be considered predeclared.
-- @return the given table, or a new table
function strict.module (name,mod,predeclared)
local mt, old_newindex, old_index, global, closed
if predeclared then
global = predeclared.__global
closed = predeclared.__closed
end
if type(mod) == 'table' then
mt = getmetatable(mod)
if mt and rawget(mt,'__declared') then return end -- already patched...
else
mod = {}
end
if mt == nil then
mt = {}
setmetatable(mod, mt)
else
old_newindex = mt.__newindex
old_index = mt.__index
end
mt.__declared = predeclared or {}
mt.__newindex = function(t, n, v)
if old_newindex then
old_newindex(t, n, v)
if rawget(t,n)~=nil then return end
end
if not mt.__declared[n] then
if global then
local w = what()
if w ~= "main" and w ~= "C" then
error("assign to undeclared global '"..n.."'", 2)
end
end
mt.__declared[n] = true
end
rawset(t, n, v)
end
mt.__index = function(t,n)
if not mt.__declared[n] and what() ~= "C" then
if old_index then
local res = old_index(t, n)
if res then return res end
end
local msg = "variable '"..n.."' is not declared"
if name then
msg = msg .. " in '"..name.."'"
end
error(msg, 2)
end
return rawget(t, n)
end
return mod
end
function strict.make_all_strict (T)
for k,v in pairs(T) do
if type(v) == 'table' and v ~= T then
strict.module(k,v)
end
end
end
function strict.closed_module (mod,name)
local M = {}
local mt = getmetatable(mod)
if not mt then
mt = {}
setmetatable(mod,mt)
end
mt.__newindex = function(t,k,v)
M[k] = v
end
return strict.module(name,M)
end
strict.module(nil,_G,{_PROMPT=true,__global=true})
return strict
|