Lua_ Modules and packages_ Loading mechanism_ Package C_ Script uninstall_ Large G table (13)

Posted by viperdk on Sat, 22 Jan 2022 06:16:52 +0100


Code cloud code link
https://gitee.com/wenwenc9/lua_pro.git

1, require

Module is similar to a package library. Starting from Lua 5.1, Lua has added a standard module management mechanism, which can put some common code in one file and call it elsewhere in the form of API interface, which is conducive to code reuse and reduce code coupling.
Lua's module is a table composed of known elements such as variables and functions. Therefore, it is very simple to create a module, that is, create a table, put the constants and functions to be exported into it, and finally return the table. The following is how to create a custom module Lua, the file code format is as follows:

module.lua

module = {}

module.constant = 'This is a constant'

function module.func1()
    io.write('This is a public function')
end

local function func2() 
    io.write('This is a private function')
end

function module.func3()
    func2()
end

return module

1, require function

  • require searches the directory to load the file
  • require will determine whether the file has been loaded to avoid repeated loading of the same file

Due to the above characteristics, require is a better function for loading libraries in Lua.

There are some differences between the path used by require and the path we see. Generally, the path we see is one
A list of directories. The path of require is a list of patterns, and each pattern indicates a pattern defined by the virtual file name (require)
Method to convert to a real file name. More specifically, each pattern is a file with optional question marks
Name. When matching, Lua will first replace the question mark with the virtual file name, and then see if such a file exists. as
If the result does not exist, continue to match with the second pattern in the same way. For example, the path is as follows:

?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua 

When you call require "lili", you try to open these files:

lili 
lili.lua 
c:\windows\lili 
/usr/local/lua/lili/lili.lua 

The only issues that require focuses on are semicolons (separators between patterns) and question marks, and other information (directory separators)
Character, file extension) is defined in the path.
To determine the path, Lua first checks the global variable Lua_ Whether path is a string. If yes, it is recognized
For this string is the path; Otherwise, require checks the environment variable lua_ The value of path. If both fail, require uses a fixed path (typical "?;?. lua")

Another function of require is to avoid loading the same file twice. Lua keeps a copy of all loaded
List of files (saved using table). If a LOADED file exists in the table, require simply returns; The virtual name of the LOADED file is retained in the table instead of the real file name. So if you use a different virtual file name to require the same file twice, the file will be LOADED twice. For example, require "foo" and require "foo.lua", the path is "?;?. lua" will load foo lua twice. We can also use global variables_ LOADED accesses the file name list so that we can judge whether the file has been LOADED; Similarly, we can use a little trick to make require load a file twice. For example, after require "foo"_ LOADED ["foo"] will not be nil, we can assign it to nil, and require "foo.lua" will load the file again.

The pattern in a path can also be a fixed path without a question mark, such as:

?;?.lua;/usr/local/default.lua 

In this case, the fixed file (of course, the fixed path) will be used when the require does not match
Path must be placed at the end of the pattern list to make sense). Before require runs a chunk, it defines a global variable_ REQUIREDNAME is the file name used to save the required virtual file. We can extend the function of require by using this technique. For an extreme example, we can set the path to "/ usr/local/lua/newrequire.lua", so that newrequire.lua will be run every time we call require in the future Lua, in this case, you can use_ The value of REQUIREDNAME to actually load the required file.

Lua provides a function called require to load modules. To load a module, simply call it. For example:

require("<Module name>")

perhaps

require "<Module name>"

After executing require, a table composed of module constants or functions will be returned, and a global variable containing the table will be defined.
After executing require, a table composed of module constants or functions will be returned, and a global variable containing the table will be defined.

-- test_module.lua file
-- module The module is mentioned above module.lua
require("module")
 
print(module.constant)
 
module.func3()

results of enforcement

This is a constant
 This is a private function!

You can define a variable name for the loaded module to facilitate calling

2, Loading mechanism

package.path = package.path..";D:/lua-wenwenc9/lua_pro/ws3c/12_Modules and packages/?.lua"

For customized modules, the module file can not be placed in any file directory. The function require has its own file path loading strategy. It will try to load modules from Lua files or C libraries.

The path require d to search for Lua files is stored in the global variable package In path, when Lua is started, the environment variable Lua will be used_ Path to initialize the environment variable. If the environment variable is not found, it is initialized with a default path defined at compile time.
Of course, without LUA_PATH, an environment variable, can also be customized and opened in the root directory of the current user profile file (if not created, you can open the. bashrc file), for example, add the "~ / lua /" path to LUA_PATH environment variable:

#LUA_PATH
export LUA_PATH="~/lua/?.lua;;"

File path with ";" The last 2 ';;' are separated by signs Indicates that the new path is followed by the original default path.
Next, update the environment variable parameters to take effect immediately.

source ~/.profile

At this time, suppose package The value of path is:

/Users/dengjoe/lua/?.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua

When you call require("module"), you will try to open the following file directory to search for the target.

/Users/dengjoe/lua/module.lua;
./module.lua
/usr/local/share/lua/5.1/module.lua
/usr/local/share/lua/5.1/module/init.lua
/usr/local/lib/lua/5.1/module.lua
/usr/local/lib/lua/5.1/module/init.lua

If the target file is found, package. Is called Load file to load the module. Otherwise, you will go to the C library.
The file path searched is from the global variable package Cpath, and this variable is obtained through the environment variable LUA_CPATH to start.
The search strategy is the same as the above, but now the search is for files of so or dll type. If you can find it, then require will pass package Loadlib to load it.

3, Package C

Lua and C are easy to combine. Use C to write packages for Lua.
Unlike the package written in Lua, C package must be loaded and connected before use. In most systems, the easiest implementation is through the dynamic connection library mechanism.
Lua provides all the functions of dynamic connection in a function called loadlib. This function has two parameters: the absolute path of the library and the initialization function. Therefore, typical call examples are as follows:
local path = "/usr/local/lua/lib/libluasocket.so"
local f = loadlib(path, "luaopen_socket")

The loadlib function loads the specified library and connects to Lua, but it does not open the library (that is, no initialization function is invoked). Instead, he returns the initialization function as a function of Lua so that we can call him directly in Lua.
If there is an error loading the dynamic library or finding the initialization function, loadlib will return nil and error information. We can modify the preceding code to detect errors and call the initialization function:

local path = "/usr/local/lua/lib/libluasocket.so"
-- perhaps path = "C:\\windows\\luasocket.dll",This is Window Under platform
local f = assert(loadlib(path, "luaopen_socket"))
f()  -- Really open the library

Generally, we expect the binary Publishing Library to contain a stub file similar to the previous code segment. When installing the binary library, you can put it in a directory at will. You only need to modify the actual path of the binary library corresponding to the stub file.
Add the directory where the stub file is located to the LUA_PATH, so you can use the require function to load the C library.

4, Script uninstall

require('Test')
print(package.loaded['Test'])
require('Test') -- Loading once does not load twice

-- uninstall
package.loaded['Test'] = nil

5, Big G table

You can print all system variables, self-defined variables and parameters in this script, which are stored in the big G table,
It is used in object-oriented creation

a = {}
b = 2
function fun()
    print('hello')
end

-- Print large G surface
for k,v in pairs(_G) do
    print(k,v)
end

a	table: 00C29018
string	table: 00C28F78
xpcall	function: 00C272A8
b	2
package	table: 00C26760
tostring	function: 00C27008
print	function: 00C26EA8
os	table: 00C28F50
unpack	function: 00C272C8
require	function: 00C27E00
getfenv	function: 00C26D48
setmetatable	function: 00C26CE8
next	function: 00C26B48
assert	function: 00C26E28
tonumber	function: 00C26F68
io	table: 00C293B0
rawequal	function: 00C26C28
collectgarbage	function: 00C26B68
arg	table: 00C29400
getmetatable	function: 00C26DE8
module	function: 00C28080
fun	function: 00C2B4C0
rawset	function: 00C26DC8
math	table: 00C29388
debug	table: 00C29108
pcall	function: 00C26F08
table	table: 00C267D8
newproxy	function: 00C20520
type	function: 00C26F48
coroutine	table: 00C26738
_G	table: 00C22FB0
select	function: 00C26C08
gcinfo	function: 00C26E88
pairs	function: 00C21348
rawget	function: 00C26C48
loadstring	function: 00C26DA8
ipairs	function: 00C21458
_VERSION	Lua 5.1
dofile	function: 00C26B88
setfenv	function: 00C26C88
load	function: 00C26CC8
error	function: 00C26D08
loadfile	function: 00C26E08

Topics: Programming lua