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. angular2+webpack的搭建过程遇到的问题记录

    最近在由于公司的项目要重构,Superiors要求将原先的Ionic1+angular1+gulp用全新的Ionic2+angular2+webpack重构.苦逼的Google了好久,环境搭建还是不太 ...

  2. metrics实践 (metrics-spring)

    这里主要介绍metrics与spring集成的使用方式. 1  添加maven依赖 <dependency> <groupId>com.ryantenney.metrics&l ...

  3. Unity3DGUI:鼠标click

    Input函数监测鼠标操作 鼠标点击事件 鼠标双击事件

  4. 基于 Consul 的 Docker Swarm 服务发现

    Docker 是一种新型的虚拟化技术,它的目标在于实现轻量级操作系统的虚拟化.相比传统的虚拟化方案,Docker 虚拟化技术有一些很明显的优势:启动容器的速度明显快于传统虚拟化技术,同时创建一台虚拟机 ...

  5. WPF 命令的简单总结

    WPF的命令Command主要解决的问题,就是代码复用.一个很重要的应用意义,在于它将很多地方需要的调用的相同操作,以统一的方式管理,却又提供了不同的访问结果. 举个例子来说,我可能通过“点击butt ...

  6. Nopi Excel导入

    http://download.csdn.net/detail/diaodiaop/7611721 using System.Collections.Generic; using System.Dat ...

  7. jQuery 设置select默认选中问题

    在进行其他操作后,恢复select默认选中 html代码: <select id="shai" style="width:150px;margin:5px 50px ...

  8. js replace(a,b)之替换字符串中所有指定字符的方法

    var str = 'abcadeacf'; var str1 = str.replace('a', 'o'); alert(str1); // 打印结果: obcadeacf var str2 = ...

  9. 中小型公司数据仓库搭建——以mysql为例

    为了方便公司的数据分析平台的独立运行和数据挖掘的探索,今年上半年在公司搭建了支持数据平台和数据挖掘的数据仓库:现就数据仓库的创建工作总结如下,供大家参考: 首先介绍下数据仓库搭建的缘由: 公司创建两年 ...

  10. ftp服务器端的安装及配置

    搭建过程 安装 vsftp 服务(yum 安装即可) 配置/etc/vsftpd/vsftpd.conf   anonymous_enable=NO #禁止匿名登录 local_enable=YES ...