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. 洛谷-神奇的幻方-NOIP2015提高组复赛

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,--,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

  2. 【IE6的疯狂之九】li在IE中底部空行的BUG

    曾经写过[IE6的疯狂之六]li在IE中底部3像素的BUG(增加浮动解决问题),原文地址:http://www.css88.com/archives/421: IE6 BUG大全: http://ww ...

  3. 【Python】回文

    首先判断一个字符串是否回文: def isPlalind(s): if len(s) == 1: return True else: return s[0] == s[-1] and isPlalin ...

  4. [SQL基础教程] 2-1 SELECT语句基础

    [SQL基础教程] 2-1 SELECT语句基础 列的查询 Syntax SELECT<列名>,..... FROM<表名>; SELECT col_1, col_2 FROM ...

  5. [河南省ACM省赛-第三届] 聪明的kk (nyoj 171)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=171 动态规划: d(i,j) = max{d(i-1, j), d(i, j-1)}+m ...

  6. html的简单表单制作...day5 php

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  7. 向多个会话窗口发送命令 -SecureCRT

    1.前提 一个服务可能部署在多台机器上,这时如果要查问题,最繁复的方法就是打开该服务的每个session,把命令在每一台机器上复制一下执行,找到相关的日志:还有一种方法就是一条命令同时向多个会话窗口发 ...

  8. JPA 系列教程21-JPA2.0-@MapKeyColumn

    @MapKeyColumn 用@JoinColumn注解和@MapKeyColumn处理一对多关系 ddl语句 CREATE TABLE `t_employee` ( `id` bigint(20) ...

  9. jq siblings()的强大之处

    在事件处理的方法里 经常遇到自己做什么效果 其他节点就做反之效果 如果用判断 可处理 但代码太啰嗦不够简单 siblings()就可以解决这一切的麻烦 意思就是 除啦我之外的其他兄弟节点 这样可以做2 ...

  10. 进程管理利器supervisor

    supervisor安装 方法一 1:用管理员安装python-setuptools suse zypper in python-setuptools centos yum install pytho ...