Deep Learning Lua--Environment Table

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)

 

Guess you like

Origin blog.csdn.net/Momo_Da/article/details/105598511