I attach a patch for the last lua revision on github [1]. It changes the "Global by default" policy to a "No default" one. This is done only in specifically marked go/end blocks. In particular:
- It adds an <erroronfreename> attribute
- It allows do/end block to have attributes
- In a do/end block with an <erroronfreename> attribute, a free name raises a compile time error instead of being translated to _ENV.name
It is just a very minimal proof of concept (e.g. there is no check of which attribute is valid for each statement), however the patch lets you to write:
```
-- toplevel works as usual
print("ok")
-- clean do block works as usual
do
print("ok")
end
-- a marked do block "Hides" the "Globals"
do <erroronfreename>
_ENV.print("ok") -- ok: _ENV is an upvalue
print("BAD") -- error: "print" is a free name in a protected block
end
-- nested block inherits the attribute
do <erroronfreename>
do
print("BAD")
end
end
```
Initially, I thought it could be useful to protect against typos, e.g. wrapping the whole script with:
```
-- copy all the needed globals into locals, e.g.
local print = print
do <erroronfreename>
-- ... whole script ...
end
```
But this pattern has some issue, for example to change a global value you have to write `_ENV.name = val`, and a typo in "name" is still not catched. (Obviously you can use static.lua, but, as observed in another thread, sometimes runtime-checks may be problematic).