• Chapter 15_4 子模块和包


      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 》

  • 相关阅读:
    CSS选择器
    JavaScript 变量、作用域和内存问题
    QTP不能打开或者新建FunctionLibrary的解决方法
    QTP场景恢复之用例失败自动截图
    QTP公开课视频-持续更新中。。。
    QTP数据驱动之读取Excel数据
    qtp与selenium2的区别
    博客园安家记录下
    HDU 5943 Kingdom of Obsession
    ORACLE将查询的多条语句拼在一个字段下
  • 原文地址:https://www.cnblogs.com/daiker/p/5867831.html
Copyright © 2020-2023  润新知