Lua Standard library-modules (Modules)

Source: Internet
Author: User

Lua Package libraries provides a simple way for LUA to load and create modules, consisting of require, module methods, and package tables.

  1. Module (name [, ...])

Function: Create a module.

module's processing flow:

Module (name, CB1, CB2, ...)

A. If package.loaded[name] is a table, then use this table as a module

B. If the global variable name is a table, use this global variable as a module

C. When the table name is not stored in either of the previous two cases, a new table is created with the value of the global name name and Package.loaded[name], and T._name is name,t._m to Module,t._package as the full name of the package ( Module name-component A.B.C); Finally, this module sets T as a new value for the new environment table and Package.loaded[name] for the current function (that is, the old environment table will not be accessible, except with the Package.seeall parameter). To be used by require

That is: Create table:t = {[Name]=package.loaded[name], ["_name"]=name, ["_m"]=t, ["_package"]=*name* (removed last ". XXXX "section)}. If name is a dot-separated string, then the resulting mod looks like this:

hello.world==> {["Hello"]={["World"]={xxxxxxx}}

D. Call CBS in turn:
CB1 (MoD), CB2 (MoD),...

E. Set the current module's environment to module, while package.loaded[name] = module

  The optional parameter after module (name) is a function that receives the module name, such as Package.seeall

When the module function is used in the modules file , as shown below;

Module "MyModule"  

is actually equivalent to the following statement:

 local  modname = "MyModule"-– defines the module name  Span style= "color: #0000ff;" >local  M = {} --  Defines the module table for return _g  [modname] = M --  Add the module table to the global variable  package.loaded  [modname] = M --  add the module table to package.loaded to prevent multiple loads of  setfenv                    (1 , M) --  Sets the module table to the function's environment table, which allows all operations in the module to be in the module table, so that the definition function is defined directly in the module table  

Through module (), you can easily write the contents of the modules. After the module instruction is run, the entire environment is compressed, so the front of the whole thing is out of sight again.  For example, after defining a test module, using the module ("Test"), the following is no longer seen in the previous global environment. What if I want to call print output debug information in this module? An easy way to do this is

Local print=printmodule("test")

So print is a local variable, and the following is also visible. Or you can use

Local _g=_gmodule("test")

Then _g.print can also be used.

And of course there is a clever way that LUA 5.1 provides an option to Package.seeall as a module ("Test", Package.seeall)

This will be OK. As to how they work, or read the source code will understand clearly some.

Specific use such as: Declaration MyModule Package

 --  File:myModule.lua  module  ( mymodule   ", package.seeall ) --  display declares a MyModule package  function   Printmsg (msg  print  ( " mymodule:   .. msg)  end  function   Setmag (msg) test.msg  = msg  end  

Call the MyModule package:

--File:myModuleTest.luaLocal Print=Print LocalMoD =require("MyModule")Print("Call mymodule start") Test={}mod.setmag ("Test module~")Print(test.msg) mod.printmsg ("Yes")

The output results are as follows:

All MyModule start
Test module~
Mymodule:yes

module("...", package.seeall)declare a package by displaying it. This is the way to see many of GitHub's earlier open source projects, but it is not recommended to use this way.

Because: 1, Package.seeall This way destroys the high cohesion of the module, originally introduced Oldmodule only want to invoke its Foo () function, but it can read and write global properties, such as Oldmodule.os.
2, the Side-effect of the module function causes it to pollute the global environment variable.
The module ("Hello.world") creates a Hello table and injects the table into the global environment variable so that modules that do not want to reference it can also invoke the Hello module method.

So it's better to implement a module by return table. Use the following:

--File:module.luaLocal Module= {}function Module. Foo ()Print("Module.foo called")Endfunction Module: Setmsg (msg) self.mmsg=msgEndfunction Module: getmsg ()returnself.mmsgEndreturn Module
-- File:myModuleTest.lua   Local require ("module") mod:setmsg ("test module~" )   -- mod.setmsg (mod, "Test module~")--equivalent upper sentence print(mod:getmsg ())

--The results are as follows: Test module~

  

  2, require (ModName)

Function: Loads the specified module.

This function first detects if there is a modname in the package.loaded table, returns the value directly, and does not load the modname through the defined loader.

1)require mechanism-related data and functions
Package.path: Save load external module (LUA "module" and "File" the demarcation of the two concepts is ambiguous, because this value at different times will play a different role) search path, this path is "template-style path", it contains an alternative symbol "?", The symbol is replaced, and Lua finds out if the file exists and invokes a particular interface if it exists. The typical values are:
"./?. Lua;. /?. Lc;/usr/local/?/init.lua "
If called in LUA Code: require ("Hello.world")
Then LUA will look in turn:
./hello/world.lua ==> Here "Hello.world" becomes "Hello/world" and replaces the model "./?. Lua
./hello/world.lc
.....
(This is similar to Python, except that __init__.py is not required, and __init__.py in Python is called)
Package.path is set when the virtual machine is started, and if there is an environment variable lua_path, use that environment variable as the
Its value, and put this environment variable in the ";;" Replace with the default value defined in Luaconf.h and use it directly if it does not exist
Default value defined by Luaconf.h

Package.cpath: Acts like Packag.path, but it is used to load third-party C libraries. Its initial value can be passed through the environment variable
Lua_cpath to set
Package.loadlib (Libname, func): Quite with the manual open C library libname, and the export function func returns, Loadlib is actually ll_loadlib

2) Find loader order:

The lookup order for require (which is the Ll_require function in Lua) is as follows:
A. First find the modelname in package.loaded, and if the module already exists, return its value directly
B. In package.preload find modelname, if preload exists, then use it as loader, call loader (L)
C. Find Lua library modelname according to Package.path mode, this library is defined by the module function, for the top-level LUA library, the file name is the same as the library name and does not require a call to explicitly call the module function in the Lua file (in Ll_ Require function can be seen in the process), that is, LUA will be based on LUA files directly complete a loader initialization process.
D. Find the C library according to Package.cpath, which is compliant with some of LUA's specifications (export has a feature-specific function interface), and Lua first loads the C library dynamically and then finds and invokes the interface of the corresponding name in the library, for example: Luaopen_hello_ World
E. Already the first "." For the partition, the module name is divided into: (Main, sub) form, according to Package.cpath find main, if present, load the library and query the corresponding interface: Luaopen_main_sub, for example: first find the Hello Library, and query Luaopen_ Hello_world interface
F. When Loder is obtained, the loader function is called with ModName as the only parameter. Of course the parameters are passed through the LUA stack, so the loader prototype must conform to the LUA specification: int lua_func (lua_state *l)

Ll_require will give the return value of this loader to package.loaded[modelname], if loader does not return a value and Package.loaded[modelname] does not exist, Ll_ Require will set Package.loaded[modelname] to True. Finally Ll_reuqire returns package.loaded [modelname] to the caller. Require will trigger an error when the load fails

3)  Another feature of require is to avoid repeatedly loading the same file two times. Lua retains a list of all the files that have been loaded ( saved using the table). If a loaded file exists in the table require simple return, the table retains the title of the loaded file withoutis a real file name. So if you use a different virtual file name to require the same file two times, the file will be loaded twice. For example require "foo" and require "Foo.lua", the path is "?;?. Lua "will load Foo.lua two times. We can also use the global variable _loaded to visit Ask the list of file names so that we can tell if the file has been loaded, and we can also use a little trick to get require to load a file two times. For example,require "foo" after _loaded["foo" will not be nil, we can assign it to Nil,require "Foo.lua" will load the file again.

Package.loaded[modname] or _loaded[modname) can be set to nil and then re-require to complete the LUA hot update function. Specific See also: Codedump

  3, Package.cpath

Function: Search path for require C loader

This value can be modified by modifying the Lua_cpath variable (luaconf.h)

  4, package.loaded

Function: A record table that lets require know which modules have been loaded, and returns this value directly if package.loaded already has a value of require

  5, Package.loadlib (Libname, funcname)

Function: Loading LUA extension Library by Dynamic connection C function library

Libname is the library file name, FuncName is the entry function (this function must be a pure C interface function C + + with extern "C" {} to restrict)

  6, Package.path

Function: Search path for require Lua loader

This value can be modified by modifying the Lua_path variable (luaconf.h)

  7, Package.preload

Function: A table to hold the Special module loader

  8. Package.seeall (module)

Function: Set a meta-table for module, the value of the __index field for this meta-table is the global environment _g. So module can access the Global environment

Note: Use this function as an option for module () (see Module () for details)

Reference article: Clickhere and here

Lua Standard library-modules (Modules)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.