lua5.1 模块理解

http://www.lua.org/manual/5.1/manual.html#pdf-module

模块

5.3 – Modules

The package library provides basic facilities for loading and building modules in Lua. It exports two of its functions directly in the global environment: require and module. Everything else is exported in a table package.

package库提供了基本的功能,可以实现加载和构建模块。

此库开放了两个接口在全局环境中(_G) require module ,

除了这两个接口,其他所有功能都开放到package表中。

实际上 require 文件 的结果 都存储在 package.loaded 表中。   例如 require “xxx”,   结果是 package.loaded[“xxx”]  = yyy (yyy 是 xxx.lua 执行结果的返回值)。

require

require (modname)

Loads the given module. The function starts by looking into the package.loaded table to determine whether modname is already loaded. If it is, then require returns the value stored at package.loaded[modname]. Otherwise, it tries to find a loader for the module.

require 语句, 会先查询 package.loaded 表, 如果表中存在, 则将 package.loaded[modname]的值作为 require 的返回值。 否则, 尝试查询模块的 loader。

To find a loader, require is guided by the package.loaders array. By changing this array, we can change how require looks for a module. The following explanation is based on the default configuration for package.loaders.

查询 loaders, 需要按照 package.loaders数组顺序查询loader。

First require queries package.preload[modname]. If it has a value, this value (which should be a function) is the loader. Otherwise require searches for a Lua loader using the path stored in package.path. If that also fails, it searches for a C loader using the path stored in package.cpath. If that also fails, it tries an all-in-one loader (see package.loaders).

首先 require 查询 package.preload表,如果失败,

然后使用 package.path存储的路径查找 lua loader, 如果失败,

然后使用package.cpath春初的路径查找 c loader, 如果失败,

则尝试 all-in-one loader。

Once a loader is found, require calls the loader with a single argument, modname. If the loader returns any value, require assigns the returned value to package.loaded[modname]. If the loader returns no value and has not assigned any value to package.loaded[modname], then require assigns true to this entry. In any case, require returns the final value of package.loaded[modname].

如果loader找到, 则 调用 此loader, 入参为一个字符串 modname。

loader(modname)

如果loader调用有返回任何值, 则设置这个返回值到 package.loaded[modname]中。

如果 loader调用没有返回值, 或者没有设置package.loaded[modname], 则 require 设置true给package.loaded[modname]。

理解: 对于lua文件, 对应的一个loader, 此loader是一个函数, 函数的环境为 require执行的环境,

lua:

local a = 111

print(a)

return a

loader:

function xx_loader( modname )

local a = 111

print(a)

return a

end

If there is any error loading or running the module, or if it cannot find any loader for the module, then require signals an error.

module

module (name [, ···])

Creates a module. If there is a table in package.loaded[name], this table is the module. Otherwise, if there is a global table t with the given name, this table is the module. Otherwise creates a new table t and sets it as the value of the global name and the value of package.loaded[name]. This function also initializes t._NAME with the given name, t._M with the module (t itself), and t._PACKAGE with the package name (the full module name minus last component; see below). Finally, module sets t as the new environment of the current function and the new value of package.loaded[name], so that require returns t.

http://www.cnblogs.com/orez88/articles/2139160.html

  • module

当在模块文件中使用module函数的时候,如下所示;

  1. module “mymodule”

实际上等同于以下的语句:

  1. local modname = “mymodule”     – 定义模块名
  2. local M = {}                               -- 定义用于返回的模块表
  3. _G[modname] = M                      -- 将模块表加入到全局变量中
  4. package.loaded[modname] = M    -- 将模块表加入到package.loaded中,防止多次加载
  5. setfenv(1,M)                               -- 将模块表设置为函数的环境表,这使得模块中的所有操作是以在模块表中的,这样定义函数就直接定义在模块表中

通过module(),可以方便的编写模块中的内容。

If name is a compound name (that is, one with components separated by dots), module creates (or reuses, if they already exist) tables for each component. For instance, if name is a.b.c, then module stores the module table in field c of field b of global a.

将 路径层级 和 命名空间层级 完美契合:

module 文件  存储在 test/newModule.lua文件中

module(..., package.seeall)

dingzhiprint = function ()

print("nasView print ----22 55")

end

调用文件, 为  test.lua, 其使用方法  与路径一致。

require("test.newModule")

test.newModule.dingzhiprint()

This function can receive optional options after the module name, where each option is a function to be applied over the module.

lua5.2 module 不建议使用原因

1、 module 的接口 增加了开发者理解难度:

需要在 module 声明前, 将需要使用的 变量 local 声明, 不能直接使用全局变量。 虽然可以应用 package.seeall 可以解决这个问题, 还是不够直接。

  1. local modname = “mymodule”     – 定义模块名
  2. local M = {}                               -- 定义用于返回的模块表
  3. _G[modname] = M                      -- 将模块表加入到全局变量中
  4. package.loaded[modname] = M    -- 将模块表加入到package.loaded中,防止多次加载
  5. setfenv(1,M)                               -- 将模块表设置为函数的环境表,这使得模块中的所有操作是以在模块表中的,这样定义函数就直接定义在模块表中

2、 module语法破坏了全局环境, 可能导致命名冲突。

module(…)用法不会导致冲突,  但是如果用户自定义 modname, 则若干模块很容易冲突,

例如 a b 两个文件夹, a/a.lua 定义了 module(“test”)   b/b.lua 也定义了 module(“test”),

则造成冲突。

http://dhq.me/lua-learning-notes-package-and-module

https://john.nachtimwald.com/2014/07/19/writing-lua-modules/

lua 5.2 推荐使用方法:

local M = {}

function M.func1()

print("func1")

end

function M.func2()

print("func2")

end

return M

local fm = require("functions_module")

fm.func1()

fm.func2()

lua 模块功能的更多相关文章

  1. lua 模块与环境

    编写一个模块的最简单方法: -- complex.lua -- 模块实际上是一个表 complex = {} -- 定义模块函数 function complex.add(c1,c2) ... end ...

  2. lua 模块

    lua 模块 概述 lua 模块类似于封装库 将相应功能封装为一个模块, 可以按照面向对象中的类定义去理解和使用 使用 模块文件示例程序 mod = {} mod.constant = "模 ...

  3. Nginx使用Lua模块实现WAF

    前言:最近一段时间在写加密数据功能,对安全相关知识还是缺少积累,无意间接触到了WAF相关知识,刚好Nginx可以实现WAF功能,也简单学习了Lua这门语言,分享下 一.WAF产生的背景 过去企业通常会 ...

  4. vim编译安装+lua模块

    vim编译安装+lua模块 使用背景:代码自动补全插件,需要安装lua模块 安装准备,首先下载安装vim所依赖的其它安装包,ncurses,lua,readline,vim 源码下载,编译安装 ncu ...

  5. 基于Metronic的Bootstrap开发框架--工作流模块功能介绍(2)

    本篇继续<基于Metronic的Bootstrap开发框架--工作流模块功能介绍>,继续介绍基于Metronic的Bootstrap开发框架的工作模块功能,介绍工作流模块中相关业务表单的界 ...

  6. 基于Metronic的Bootstrap开发框架--工作流模块功能介绍

    在很早之前的随笔里面,已经介绍了WInform框架中工作流模块的功能,不过由于工作流模块中界面处理部分比较麻烦,一直没有在Bootstrap框架中进行集成,最近由于项目的关系,花了不少精力,把工作流模 ...

  7. lua模块demo(redis,http,mysql,cjson,本地缓存)

    1. lua模块demo(redis,http,mysql,cjson,本地缓存) 1.1. 配置 在nginx.conf中设置lua_shared_dict my_cache 128m; 开启ngi ...

  8. Winform开发框架中的内容及文档管理模块功能介绍

    在开发项目的时候,我们有一些场景需要编辑一些HTML文档,作为内容发布系统的一部分,有时候也需要对一些文档如WORD文档进行编辑管理,这样需要我们对这些内容及文档进行合适的管理.本文主要介绍在WInf ...

  9. Lua模块的加载与内存释放

    今天早上听说一件事情让我觉得很诡异的事情:公司线上的一款游戏,加载一份配置资源后,内存涨了几十M,然后内存再也下不来了.因为好奇,所以要来了最大的一个配置文件(4.5M,去除空格与换行后的大小),进行 ...

随机推荐

  1. NOIp 2013 #2 花匠 Label:爆0的Water

    题目描述 花匠栋栋种了一排花,每株花都有自己的高度.花儿越长越大,也越来越挤.栋栋决定 把这排中的一部分花移走,将剩下的留在原地,使得剩下的花能有空间长大,同时,栋栋希 望剩下的花排列得比较别致. 具 ...

  2. 51Nod 1046 A^B Mod C Label:快速幂

    给出3个正整数A B C,求A^B Mod C.   例如,3 5 8,3^5 Mod 8 = 3. Input 3个正整数A B C,中间用空格分隔.(1 <= A,B,C <= 10^ ...

  3. C#文字样式

    [字体] 中文名称 英文名称宋体 SimSun黑体 SimHei微软雅黑 Microsoft YaHei微软正黑体   Microsoft JhengHei新宋体   NSimSun新细明体 PMin ...

  4. JS调用水晶报表打印翻页按钮事件

    默认的水晶报表打印按钮.翻页按钮太小,并且样式不好调整,考虑自己做一个按钮,然后调用水晶报表的按钮事件. 在实际操作中发现可以在.net按钮的服务器端事件中调用翻页方法: CrystalReportV ...

  5. iis中MIME类型的介绍与使用

    今天在服务器上碰到由.mp3格式转化生成的.m4r格式不能被浏览器访问(MP3与m4r在同个域名目录下eg:www.abc.com/1.m4r) 解决办法: 1.选中文件所在的站点: 2.找到MIME ...

  6. Convert between cv::Mat and QImage 两种图片类转换

    在使用Qt和OpenCV混合编程时,我们有时需要在两种图片类cv::Mat和QImage之间进行转换,下面的代码参考了网上这个帖子: //##### cv::Mat ---> QImage ## ...

  7. Hadoop.2.x_伪分布环境搭建

    一. 基本环境搭建 1. 设置主机名.静态IP/DNS.主机映射.windows主机映射(方便ssh访问与IP修改)等 设置主机名: vi /etc/sysconfig/network # 重启系统生 ...

  8. MyBatis环境搭建配置文件+入门视频下载

    1.MyBatis优点 操作简单话,代码量少,效率高,成本就降低了 2.MyBatis缺点 参数只能限制为一个 selece语都要手动来写 3.与JDBC的关系:是对JDBC的扩展 把sql语句和ja ...

  9. nyoj-204

    描述国王有一个魔镜,可以把任何接触镜面的东西变成原来的两倍——只是,因为是镜子嘛,增加的那部分是反的. 比如一条项链,我们用AB来表示,不同的字母表示不同颜色的珍珠.如果把B端接触镜面的话,魔镜会把这 ...

  10. 累积进度图及本周PSP饼状图

    每周进度   项目:词频统计  项目类型:个人项目 项目完成情况:已完成 C类别 C内容 S开始时间 E结束时间 I间隔 T净时间 分析 需求,设计 10:00 10:49 20 29 编码 代码的实 ...