Lua支持具有层级性的模块名,可以用一个点来分隔名称中的层级。

比如,一个mod.sub模块,它就是mod的子模块。一个包(package)就是一个完整的模块树。

当你require "mod.sub"时,require首先会用"mod.sub"作为key,去询问package.loaded 然后找package.preload 表。这时模块中的点" . "没有任何特殊意义。

然而当搜索一个定义子模块的文件时,require会将点转换为另一个字符——“系统目录分隔符”。

转换之后,require就像搜索其他名称一样来搜索这个名称。例如,假设路径为:

./?.lua ; /usr/local/lua/?.lua;/usr/local/lua/?/init.lua

调用require "a.b" 后:

./a/b.lua
/usr/local/lua/a/b.lua
/usr/local/lua/a/b/init.lua

通过这样的加载策略,就可以将一个包中的所有模块组织到一个目录中。

例如,一个包中有模块p、p.a和p.b,那么它们对应的文件名就分别为p/init.lua ,p/a.lua和p/b.lua,它们都是目录p下的文件。

Lua使用的目录分隔符是编译时配置的,可以是任意的字符串。

由于C函数名中不能包含点,因此一个用C编写的子模块a.b无法导出函数luaopen_a.b。

require会将点转换为下划线。例如一个名为a.b的C程序库就应将其初始化函数命名为luaopen_a_b。

在此可以巧用连字符,来实现一些特殊的效果。例如,有一个C程序库a,现在想将它作为mod的一个子模块。

那么就可以将文件名改为mod/v-a ,当require “mod.v-a”时,require就会找到改名后的文件mod/v-a及其中的luaopen_a函数(适应于Lua5.2版本)。

require在加载C子模块时还有一些选项。当它无法找到对应的Lua文件或C程序库时,它会再次搜索C路径,不过这次将以包的名称来查找。

例如一个程序require子模块a.b.c,无法找到文件a/b/c时,再次搜索就会找到文件a。

如果找到了c程序库a,require就查看该程序库中是否有luaopen_a_b_c函数。

这项功能使得一个发行包可以将几个子模块组织到一个单一C程序库中,并且具有各自的open函数。

从Lua的观点看,同一个包中的子模块除了它们的环境table是嵌套的之外,它们之间并没有显式的关联性。

require模块a并不会自动地加载它的任何子模块。同样,require子模块a.b也并不会自动地加载a。

当然,如果包的实现者愿意,他完全可以实现这种关联。

例如:模块a的一个子模块在加载时会显式地加载a。

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

Chapter 15_4 子模块和包的更多相关文章

  1. Chapter 15_0 模块和包

    通常,Lua不会设置规则,相反会提供很多强有力的机制来使开发者有能力实现出最适应的规则. 然而,这种方法对于模块就不行了.模块系统的一个主要目标是允许以不同的形式来共享代码. 但若没有一项公共的规则就 ...

  2. python 深入模块和包

    模块可以包含可执行语句以及函数的定义. 这些语句通常用于初始化模块. 它们只在 第一次 导入时执行.只在第一次导入的时候执行,第一次.妈蛋的第一次...后面再次导入就不执行了. [1](如果文件以脚本 ...

  3. WAP调用微信支付https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1

    公司做的一个购物网站 之前微信版的网站要搬在webView上   可是微信支付是个问题 , 在外部浏览器怎么都发不起微信请求 , 原因是因为页面调用的微信浏览器自带JSAPI 在外部浏览器无法调用,但 ...

  4. Python 中包/模块的 `import` 操作

    版权声明:博客为作者原创,允许转载,但必须注明原文地址: https://www.cnblogs.com/byronxie/p/10745292.html 用实例来说明 import 的作用吧. 创建 ...

  5. Lua中的模块与包

    [前言] 从Lua5.1版本开始,就对模块和包添加了新的支持,可是使用require和module来定义和使用模块和包.require用于使用模块,module用于创建模块.简单的说,一个模块就是一个 ...

  6. 【Lua】模块与包

    定义:         从用户观点来看,一个模块就是一个程序库,可以通过require来加载(require用于使用模块,module用于创建模块),然后便得到了一个全局变量,表示一个table,这个 ...

  7. Python包模块化调用方式详解

    Python包模块化调用方式详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一般来说,编程语言中,库.包.模块是同一种概念,是代码组织方式. Python中只有一种模块对象类型 ...

  8. 【Python五篇慢慢弹(4)】模块异常谈python

    模块异常谈python 作者:白宁超 2016年10月10日12:08:31 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondo ...

  9. lua学习项目笔记

    这几天草草的浏览了一下电子版的<lua程序设计>,没有懂的地方就自动忽略了,挑拣了一些可以理解的部分一直在推进.推进至后面的时候已经浑浑噩噩的了,有种想看完这本书的强迫症的感觉.推进CAP ...

随机推荐

  1. Oracle odi 数据表导出到文件

    最近新客户要求,以EXCEL数据方式,将数据表的内容,通过AS2协议传输到客户那边,本来打算使用存储过程直接输出EXCEL,但一想,ODI这么强大的工具应该可以直接进行转换,所以参考了一下官方标准文档 ...

  2. Tiny6410之MMU开启

    存储管理单元存储管理单元MMU概述 在ARM系统中,存储管理单元MMU主要完成以下工作:1.虚拟存储空间到物理存储空间的映射.在ARM中采用页式虚拟存储管理.他把虚拟地址空间分成一个个固定大小的块,每 ...

  3. 自定义dialog自动弹出软键盘

    1.解决无法弹出输入法: 在show()方法调用之前,用dialog.setView(new EditText(context))添加一个空的EditText,由于是自定义的AlertDialog,有 ...

  4. 转:【iOS开发每日小笔记(十一)】iOS8更新留下的“坑” NSAttributedString设置下划线 NSUnderlineStyleAttributeName 属性必须为NSNumber

    http://www.bubuko.com/infodetail-382485.html 标签:des   class   style   代码   html   使用   问题   文件   数据 ...

  5. 伪AP检测技术研究

    转载自:http://www.whitecell-club.org/?p=310 随着城市无线局域网热点在公共场所大规模的部署,无线局域网安全变得尤为突出和重要,其中伪AP钓鱼攻击是无线网络中严重的安 ...

  6. 使用eclipse XML catalog绑定dtd文件

    有时候我们想编辑struts或spring的xml配置文件的时候,输了“<”之后eclipse却没有提示关键字,这是因为eclipse需要到网络下载dtd文件而由于网络原因没下载下来所以无法提示 ...

  7. 特性(Attributes)

    用以将元数据或声明信息与代码(程序集.类型.方法.属性等)相关联.特性与程序实体相关联后,即可在运行时用反射技术查询特性. 例如,在一个方法前标注[Obsolete]特性,则调用该方法时VS则会提示该 ...

  8. GoogleCodeJam

    2016年没有参赛,在师兄的介绍下,试了一下简单的一题,需要注意的是读写数据的形式还有具体代码. 2016资格赛 A题 Problem Bleatrix Trotter the sheep has d ...

  9. Ubantu安装mysql

    在Linux下MySQL的安装,我一直觉得挺麻烦的,因为之前安装时就是由于复杂的配置导致有点晕.今天,需要在Linux下用Qt连接MySQL.遂安装配置了一把. 1)首先检查系统中是否已经安装了MyS ...

  10. Java之IO流

    目录: 1.文件编码 2.File类 3.RandomAccessFile 4.字节流 5.字符流 6.对象的序列化和反序列化 1.文件编码 1)相关知识点 八进制和十六进制的表示方式:八进制前面加0 ...