15.5 Submodules and Packages
子模块和包
Lua allows module names to be hierarchical, using a dot to separate name levels. For instance, a module named mod.sub is a submodule of mod. Accordingly, you may assume that module mod.sub will define all its values inside a table mod.sub, that is, inside a table stored with key sub in table mod. A package is a complete tree of modules; it is the unit of distribution in Lua.
Lua允许模块名为分层的,用点号分隔名字层次。例如,名为mod.sub的模块是mod的子模块。因此,你可以假定模块mod.sub会在表mod.sub内定义它的所有值,即,在表mod中以sub为键存储的表内。包是模块的完全树;它是Lua中的分发单元。
When you require a module called mod.sub, require queries first the table package.loaded and then the table package.preload using the original module name "mod.sub" as the key; the dot has no significance whatsoever in this search.
当你require名为mod.sub的模块时,require首先用原始模块名"mod.sub"作为键查询表package.loaded,然后是表package.preload;在该搜索中不考虑点号的意义。
----------------------- Page 10-----------------------146
However, when searching for a file that defines that submodule, require translates the dot into another character, usually the system's directory separator (e.g., '/' for Unix or '\' for Windows). After the translation, require searches for the resulting name like any other name. For instance, assuming the path
raner,当查询定义了子模块的文件时,require把点号转换成另一个字符,通常是系统的目录分隔符(举例来说,Unix的'/'或Windows的'\')。在转换之后,require同任何其他名字一样搜索合成的名字。例如,假定路径
./?.lua;/usr/local/lua/?.lua;/usr/local/lua/?/init.lua
and '/' as the directory separator, the call require "a.b" will try to open the following files:
以及'/'作为目录分隔符,调用require "a.b"将试图打开下列文件:
./a/b.lua
/usr/local/lua/a/b.lua
/usr/local/lua/a/b/init.lua
This behavior allows all modules of a package to live in a single directory. For instance, if a package has modules p, p.a, and p.b, their respective files can be named p/init.lua, p/a.lua, and p/b.lua, with the directory p within some appropriate directory.
该行为允许一个包的所有模块存在于单个目录中。例如,如果一个包有模块p、p.a和p.b,连同某个合适目录内的目录p,它们各自的文件可被命名为p/init.lua、p/a.lua和p/b.lua。
The directory separator used by Lua is configured at compile time and can be any string (remember, Lua knows nothing about directories). For instance, systems without hierarchical directories can use a '_' as the "directory" separator, so that require "a.b" will search for a file a_b.lua.
Lua用的目录分隔符是在编译时配置的,并且可为任何字符串(记住,Lua对目录一无所知)。例如,不带层次目录的系统可用'_'作为"目录"分隔符,这样require "a.b"将查找文件a_b.lua。
C-function names cannot contain dots, so a C library for submodule a.b cannot export a function luaopen_a.b. Here require translates the dot into another character, an underscore. So, a C library named a.b should name its initialization function luaopen_a_b. We can use the hyphen trick here too, with some subtle results. For instance, if we have a C library a and we want to make it a submodule of mod, we can rename the file to mod/-a. When we write require "mod.-a", require correctly finds the new file mod/-a as well as the function luaopen_a inside it.
C函数名不能包含点号,所以子模块a.b的C库不能导出函数luaopen_a.b。此处require把点号转成其他字符,下划线。所以,名为a.b的C库应当命名其初始化函数为luaopen_a_b。此处我们也能用连字符技巧,附带着一些微妙的结果。例如,如果我们有个C库a并且我们像把它作为mod的子模块,我们可重名文件为mod/-a。当我们写require "mod.-a"时,require正确地找到了新文件mod/-a及其内的函数luaopen_a。
As an extra facility, require has one more option for loading C submodules. When it cannot find either a Lua file or a C file for a submodule, it again searches the C path, but this time looking for the package name. For example, if the program requires a submodule a.b.c, and require cannot find a file when looking for a/b/c, this last search will look for a. If it finds a C library with this name, then require looks into this library for an appropriate open function, luaopen_a_b_c in this example. This facility allows a distribution to put several submodules together into a single C library, each with its own open function.
作为一个额外功能,require还有个用于加载C子模块的选项。当不能为子模块找到Lua文件或C文件时,它再次搜索C路径,但这次查找的是包名。例如,如果程序require子模块a.b.c,并且当查找a/b/c时require找不到文件,这个最后的搜索将查找a。如果用该名字找到C库,则require在该库中查找打开函数,本例中是luaopen_a_b_c。这个功能允许分发包把若干子模块合并放在单个C库中,每个带有自己的打开函数。
The module function also offers explicit support for submodules. When we create a submodule, with a call like module("a.b.c"), module puts the environment table into variable a.b.c, that is, into a field c of a table in field b of a table a. If any of these intermediate tables do not exist, module creates them. Otherwise, it reuses them.
module函数也对子模块提供显式地支持。当我们用类似module("a.b.c")的调用创建子模块时,module把环境表放入变量a.b.c,即,放入表a的字段b中的表的字段c中。如果这些中间表中的任何一个不存在,module会创建它们。否则,它就重用它们。
From the Lua point of view, submodules in the same package have no explicit relationship other than that their environment tables may be nested. Requiring a module a does not automatically load any of its submodules; similarly, requiring a.b does not automatically load a. Of course, the package implementer is
----------------------- Page 11-----------------------147
free to create these links if she wants. For instance, a particular module a may start by explicitly requiring one or all of its submodules.
从Lua的观点来看,相同包中的子模块没有显式地关系,除了它们的环境表可能是嵌套的。require模块a不会自动地加载它的子模块;类似地,require a.b不会自动地加载a。当然,如果需要,包的实现者可自由地创建这些连接。例如,独特的模块a可以由显式地require其一个或全部子模块开始。
阅读(1119) | 评论(0) | 转发(0) |