After learning the function, a bunch of functions become a module, and a bunch of modules is a package. Learn how to write a module and how to call a module today.
I. INTRODUCTIONThe sense of Lua is simplicity, freedom, and a universal table that can handle everything. LUA has provided 5.1 of the two functions of require (for loading modules) and module (for creating modules), which are available from the beginning of the start, to add support to the module, and, of course, not using these two keywords can be loaded with table's own implementation module.The module is a library that can be loaded via require, and then we get a global variable, which is a table containing all the contents of the module. In fact, feeling require is like # include, including the content we need. Let's look at a simple example:
--Load another module require "mod"--Call the Func function in another module Mod.func ()
Of course, you can also set the module to a shorter name for local use, or set a function in the module to a shorter name:
--Set the local name of the module local m = require "mod"--set module function local name locally f = m.func--use M.func ()--or F ()
Two. About Global variablesThe variables we used earlier, if not the local keyword, are global variables. LUA saves all global variables in a regular table called "Environment", which is named _g. This implementation does not require additional data structures for global variables on one hand, and we can manipulate the global table as well as the normal table.An example, look at the _g in the gods, the LUA code is as follows:
--Define a global variable a = 100;--define global function TestFunc () print ("hehe") end--output LUA global variables for n in pairs (_g) doprint (n) End
Results: Ipairs
Load
Package
Require
Coroutine
Select
Pairs
Rawlen
Tonumber
Assert
Type
Os
Io
Math
Debug
Next
Setmetatable
Error
Rawset
Tostring
Dofile
_version
Getmetatable
Print
Table
Rawequal
String
Rawget
_g
TestFunc
Pcall
Utf8
Xpcall
LoadFile
a
CollectGarbage
Please press any key to continue ...
We define two global variables and functions ourselves, do not write local is global, and then print all the global variables, and find that both are also being typed out. Others are familiar, such as ToString and so on. However, in this case, if our program is relatively large, then it will be particularly messy. Everyone is a global, like looking for a function is also more laborious, there may be a naming conflict, this time, the module will be the debut.
Three. The simplest way to write a simple module is to create a global table, then write a bunch of functions, add it to the table, and then return the table at the end of the module, for example:
In this way, one of the simplest modules is written, and when we use it, we just need to load the module. However, the design of this module has a lot of flaws, but as a test for the time being enough, first see how to use this module.
Four. Use a single moduleLoading a module is relatively straightforward and can be done with require. is require "module name", in fact, require is responsible for a loading process, about table, etc. are written inside the module, and return to require. Detailed instructions on require:
function require (name) if not package.loaded[name] then<span style= "White-space:pre" ></span>-- To determine if the module has been loaded, avoid repeatedly loading local loader = findload (name) if loader = = Nil then error ("Unable to load module"). Name) End Package.loaded[name] = true--to avoid a dead loop when loading recursively. Local res = loader (name) <span style= "White-space:pre" ></span>--initialization module if res ~= nil Then Package.loaded[name] = Res end End return package.loaded[name]end
Analyze the above actions:1. When we give the module name, LUA does not have the brain to load, but first go to package.loaded this table to see, if it already has this module, then will not repeat loading this module. The relevant modules are then loaded via loader. If we want to force a reload of a module, we need to remove it first, package.loaded["mod"]=nil, and then require again.2. About Findload, because LUA supports LUA itself to load modules, it also supports loading C library modules, loading LUA modules using LoadFile, loading C libraries using Loadlib. Note that this step of LUA does not run these modules, just load.3. If the load is started, Package.load[mod] is set to true to prevent the loading of the module when it is associated with loading, resulting in a dead loop.4. After loading, the package.loaded[mod] is placed in the loaded module name, note that this place, if the loader does not return the module name, that is, when we write the module does not return the name, then return the value in the package.loaded.
Use the modules written above: module files Func.lua
Test file Test.lua:
Local m = require "func"--use the contents of the module M.test1 () M.test2 () print (m.num) print ("\ n")--take a look at the global variable for the case of N in Pairs (_g) doprint (n) End
Results: Test1 func!
Test2 func!
10
Setmetatable
Rawget
Next
Tostring
Getmetatable
Load
Rawset
Pairs
Pcall
Os
Coroutine
Xpcall
Dofile
Print
Select
Type
Table
Tonumber
func
Error
Debug
Utf8
Math
Ipairs
LoadFile
Rawlen
String
CollectGarbage
_version
Rawequal
Io
Package
Require
_g
Assert
Please press any key to continue ...
As we can see, we use the content in another module to realize the modularity of the function. Moreover, this time the global variables only the Func one, that is, our module, no longer cause a particularly troublesome naming conflicts and so on.
Questions about the module path:There is also a very important question, we have written a module, where to put in order to be LUA loading it? According to international practice, put in the current path is certainly possible, just the example is to put Test.lua,func.lua in the compiled LUA interpreter path.when searching for a file, many on windows are searched according to the Windows environment variable path, and the path used by require is different from the traditional path, and the path used by require is a series of patterns. Each of these is a way to convert the module name to a file name. Require will replace each "with a module name? , and then, based on the results of the substitution, checks for the existence of such a file, and if it does not exist, it tries the next item. Each item in the path is separated by a semicolon, such as a path to the following string:
?;?. lua;c:\windows\?;/ Usr/local/lua/?/?. Lua
Then, LUA will try to load the following:
Modmod.luac:\windows\mod/usr/local/lua/mod/mod.lua
So, we know the default rules for LUA loading, but what if we want to put the LUA stuff in a directory and change the default setting? The above list is stored in a field in the package, and Lua is separate from the LUA module and the C module, and Lua's path is in Packet.path, and C is in Packet.cpath. Let's print and see:
--Output LUA default load search path print ("Lua:", Package.path)-output c default load search path print ("C:", Package.cpath)
Results: Lua:c:\users\puppet_master\desktop\luatest\lua scrip\lua\?. Lua C:\Users\puppet_master \desktop\luatest\lua Scrip\lua\?\init.lua; C:\Users\zhangjian \deskto
P\luatest\lua scrip\? Lua C:\Users\puppet_master\Desktop\LuaTest\Lua Scrip\?\ini
T.lua; C:\Users\puppet_master\Desktop\LuaTest\Lua scrip\. \share\lua\5.3\?. Lua C:
\users\puppet_masterdesktop\luatest\lua scrip\. \share\lua\5.3\?\init.lua;. \?. L
The. \?\init.lua
C:c:\users\puppet_master\desktop\luatest\lua scrip\? Dll C:\Users\puppet_master\Desktop\LuaTest\Lua scrip\. \lib\lua\5.3\?. Dll C:\Users\puppet_master\Desk
Top\luatest\lua Scrip\loadall.dll;. \?. Dll
Please press any key to continue ...
Good big bunch, then, if we want to change, where to change it? Of course, good change, we have LUA source Ah, want to change what to change. This path is defined in the Lua_path in luaconf.h:
#define Lua_path_default Lua_ldir "? Lua; " Lua_ldir "? \\init.lua;" Lua_cdir "?. Lua; " Lua_cdir "? \\init.lua;" Lua_shrdir "?. Lua; " Lua_shrdir "? \\init.lua;" ".\\?. Lua; " ". \\?\\init.lua" #define Lua_cpath_default lua_cdir "?. DLL; " Lua_cdir ". \\lib\\lua\\ "Lua_vdir" \ \?. DLL; " Lua_cdir "Loadall.dll;" ".\\?. Dll
If you want to make changes, you can change it.
Questions about module names and module filenames: I feel the same way. Save a lot of trouble, fortunately remember.
Five. Write a real module on which a test is a module, but the module is riddled with holes and is very not strict. Now, let's modify this module incrementally:
In order to facilitate the modification of the module name: The above module, directly define a global variable, in order to prevent conflicts, this global variable must be relatively long, the module each thing to add such a long prefix is obviously inappropriate, more to name is, into the I want to get rid of the module name, then, All the names have to be re-written, this is a disaster. So, a lazy approach arises spontaneously:
The method is to use a local, simple variable, manipulate the local content, the content is created, the table reference to the real global reference, and then return the real module name.
What happens if the module name and the file that contains the module are different names? I don't know, the truth speaks louder than words:
Func.lua file:
Test.lua file:
--require must be with the module file name, directly to the module name can not be found-the filename here does not consider the problem of suffixes, LUA will automatically complete the suffix require "func" for the N in pairs (_g) doprint (n) End
Results: Xpcall
CollectGarbage
Utf8
Require
Next
Select
Package
Rawset
Error
Ipairs
Tostring
Getmetatable
Rawequal
Type
Dofile
Table
Os
Print
Coroutine
String
Setmetatable
Load
Pairs
Rawlen
MoD
_g
Debug
LoadFile
Pcall
Io
Assert
Tonumber
Math
_version
Rawget
Please press any key to continue ...
example, the module name is mod, the module file named Func,require is followed by the file name, but after loading it is still the original name of the module. So, this mess, in general, a file as a module is good, so the file name and the module name is still the same as good, or load the name and use the same name, the egg hurts like hell.
Change the name of the module by changing the name: Since a module is a file, it would like to lazy, when we want to change the name of the word, the filename can be changed to get rid of the module name, then how good ah. Here is an example:
--Define a module--because the Require function will pass the required module name to the function, so ... It represents the module name local ModName = ...--local module name locally M = {}--true module name direct ancestor to global variable _g[modname] = m--Module internal content Plus module name function m.test1 () print (" Test1 func! ") Endfunction M.test2 () print ("Test2 func!") Endm.num = 10
Thus, when require this module, the module name is passed to ..., this is the module name, is the file name. So, we don't need to define the file name ourselves.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
LUA Learning notes-modules and packages