lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Why upvalues cause no error?

local b="upvalue"

function test()
  local print=print
  do <erroronfreename>
    print("b=",b) -- wtf? no error
  end
end

test()

пн, 22 июл. 2019 г. в 10:40, pocomane <pocomane_7a@pocomane.com>:
>
> 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).
>
> pocomane
>
> [1] https://github.com/lua/lua/commit/1fb4d539254b67e7e35ed698250c66d1edff0e08
>