[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [proposal / postulation]: global keyword that works with lua as config file
- From: Philipp Janda <siffiejoe@...>
- Date: Mon, 31 Mar 2014 02:31:55 +0200
Am 31.03.2014 01:09 schröbte Tim Hill:
[...]
To my mind “the Lua way” is have as LITTLE policy as is practical.
The question, therefore, is really this: is it sufficiently useful to
have a policy-based method to manage global variable declaration to
justify it’s addition? Notice that this has nothing to do with HOW
such a policy is realized. This is because policies solve issues of
standardization, while the realization of policies involve issues of
efficiency and compatibility (and, dare i say it, elegance).
The OP points out that the problem with existing
implementations/work-arounds/hacks (choose your word) is that they
all collide with 3rd party code such as libraries. I’ve had this
issue as well; it doesn’t really matter what you do with the existing
solutions, they only really work if you have total control of 100% of
the source in your project.
That's not true. It's just that the `strict.lua` provided by the Lua
authors *as an example* does not handle that case (to keep it simple, I
guess). You can have each module author choose the method he/she wants
to use to catch unwanted globals, no policy needed here at all. This is
obviously true for static offline approaches, and for the dynamic
approaches I've thrown together and attached a proof of concept based on
the original `strict.lua`. Use it via
require 'mstrict'() -- notice the extra pair of parentheses
in every file you want to. No third party modules are harmed in the
process. Global assignments at the top level still count as
declarations. Have fun!
[...]
—Tim
Philipp
-- modified/modular strict.lua
-- distributed under the Lua license: http://www.lua.org/license.html
local assert = assert
local V = assert( _VERSION )
local _G = assert( _G )
local error = assert( error )
local setmetatable = assert( setmetatable )
local setfenv = assert( V ~= "Lua 5.1" or setfenv )
local require = assert( require )
local debug = require( "debug" )
local d_getinfo = assert( debug.getinfo )
local d_setupvalue = assert( V == "Lua 5.1" or debug.setupvalue )
local declared = {}
local meta = {}
local strict_G = setmetatable( {}, meta )
local function what()
local d = d_getinfo( 3, "S" )
return d and d.what or "C"
end
function meta.__newindex( _, n, v )
if _G[ n ] == nil and not declared[ n ] then
local w = what()
if w ~= "main" and w ~= "C" then
error( "assign to undeclared variable '"..n.."'", 2 )
end
declared[ n ] = true
end
_G[ n ] = v
end
function meta.__index( _, n )
local v = _G[ n ]
if v == nil and not declared[ n ] and what() ~= "C" then
error( "variable '"..n.."' is not declared", 2 )
end
return v
end
return function()
if V == "Lua 5.1" then
setfenv( 2, strict_G )
elseif V == "Lua 5.2" or V == "Lua 5.3" then
local info = d_getinfo( 2, "f" )
d_setupvalue( info.func, 1, strict_G )
else
error( "unsupported Lua version", 2 )
end
end