Lua language saves the global environment itself in the global variable _G, and outputs the names of all global variables in the global environment as follows:
for n in pairs(_G) do print(n) end
- Global variables with dynamic names
The acquisition of global variables in another variable,
value = load("return"..varname)() 和
value = _G[varname] has the same effect, the latter is an order of magnitude more efficient.
- Global variable declaration
Global variables can be used without declaration, to detect all non-existent accesses of the global table, as follows:
setmetatable(_G,{
__newindex = function (_,n)
error("attempt to write to undeclared varibale "..n,2)
end,
__index = function (_,n)
error("attempt to read to undeclared varibale "..n,2)
end,
})
Of course you can use rawset and rawget to bypass the meta method.
- Non-global variables
Free name (free name) such as: x is equivalent to _ENV.x, _ENV itself is a local variable, it is an arbitrary table, called an environment.
The way Lua handles global variables:
Before compiling all the code, create a local variable _ENV in the outer layer;
All free names var are transformed into _ENV.var;
The function load uses the global environment to initialize the first up value of the code segment, which is a table maintained internally by the lua syntax.
- Use _ENV
The code segment (a file) has a _ENV variable. _ENV = nil will prevent subsequent code from directly accessing global variables. The main purpose of _ENV is to change the environment where the code segment is used. Use inheritance to load the old environment as follows:
local newgt = {}
setmetatable(newgt, {__index = _G})
_ENV = newget
Any assignment takes place in the new table. Only _G can be used to modify variables in global variables.
- Environment and modules
_ENV solves the pollution of global variables.
- _EVN and load
Load usually initializes the value _ENV on the loaded code segment to the global environment, and there is an optional parameter to specify a different initial value for _ENV.
env = {}
loadfile("config.lua","t",env)()
Similar to running in the sandbox.
Run a piece of code several times, each time in a different environment, the two options are as follows:
The first one uses debug.setupvalue(f,1,env)
The first parameter is the specified function, the second parameter is the up value index (always 1), and the third parameter is the new up value. [Depend on the debugging library, break the visibility rules]
The other is to modify the code segment every time it is loaded, as follows:
lua把所有代码段当做可变长参数函数进行编译,多出来这一行会把传给代码段的第一个参数赋值给_ENV,从而改变环境。
prefix = "_ENV = ...;"
f = loadwithprefix(prefix,io.lines(filename,"*L"))
...
env1 = {}
f(env1)
env2 = {}
f(env2)