[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: In praise of globals
- From: Dirk Laurie <dirk.laurie@...>
- Date: Wed, 17 Apr 2013 14:46:55 +0200
2013/4/17 Thomas Jericke <tjericke@indel.ch>:
> I gave you the answer already, it is not the same thing if you do the check
> at runtime as if you do it at compile time.
>
> Phillipp Janda said it very well in his example:
>> It's better to find that out when loading the game and not when you
>> are in the middle of a group of monsters.<<
>
> Just in our case, its not a game and we aren't talking about monsters, it's
> a real machine with real components. And if you get stuck in the middle of a
> script, you will have to recover from that state, you can't just restart the
> program.
So what you really need is not a change to the language, it's enhanced
"require", "load", "loadfile" and "dofile" functions with an optional argument
to make the load fail if the function ever generates a write to _ENV.
At most a backward-compatible change to the standard libraries.
I could support that.
But is even that really necessary? The enhanced functions can easily
be written in Lua. Here is a proof-of-concept. I don't claim it is bug-free,
but at least it catches the typo in
"local t; f="local x,y; x,yu = 0,1; return x+y"
--- ban_global.lua (c) Dirk Laurie 2013, Lua-style MIT license
--
-- load = require"ban_global" replaces your load function by one that
-- rejects a function if an assigment into _ENV occurs in it.
local load, dump, open, run = load, string.dump, io.open, io.popen
return function(str)
local f, msg = load(str)
if not f then return f,msg end
local tmpfilename = "/tmp/_ban_global.luac" -- customize this
open(tmpfilename,"w"):write(dump(f)):close()
command = "luac -l -p "..tmpfilename
for l in run(command):lines() do
if l:match("SETTABUP.* _ENV ") then
return nil,"banned assigment to global LHS"
end
end
return f
end