Module 如何在一条语句中要求多个模块?
我希望同时需要几个Lua模块,类似于Java中的星号符号(Module 如何在一条语句中要求多个模块?,module,lua,wildcard,packages,require,Module,Lua,Wildcard,Packages,Require,我希望同时需要几个Lua模块,类似于Java中的星号符号(import Java.awt.*)。这是我在子目录中组织模块的结构: <myapp> -- calculations -- calc1 -- calc2 -- calc3 -- helper -- help1 -- help2 -- print --graphprinter --matrixprinter 我更喜欢自动的mul
import Java.awt.*
)。这是我在子目录中组织模块的结构:
<myapp>
-- calculations
-- calc1
-- calc2
-- calc3
-- helper
-- help1
-- help2
-- print
--graphprinter
--matrixprinter
我更喜欢自动的multi-require,它从模块路径派生本地表名,并且一次需要一个完整的子路径。这可能是以下格式:
require(“myapp.helper.print.*)
。自动为子目录的每个模块创建本地表名,这样就不会有任何差异,因为我需要每个模块都创建本地表名。为什么不为每个需要所有其他库的文件夹编写一个init.lua
文件呢
例如,在计算中,您编写的文件包含
return {
calc1 = require "calc1";
calc2 = require "calc2";
calc3 = require "calc3";
}
然后您可以只编写calculations=require“calculations”
,它将自动加载计算。calc
这可以对整个目录结构执行,并且require“helper”
可以调用require“help1”
,这反过来调用require“print”
,最后您可以在helper.help1.print中找到您的函数。
简要说明其工作原理:当您运行
require“library”
时,lua将尝试包含名为library.lua的文件或位于library
目录中的文件init.lua
。这也是为什么需要“dir.lib”
而不是需要“dir/lib”
的原因;因为,如果操作正确,当您只需要“dir”
时,它将返回一个包含字段lib
的表,因此您可以作为dir.lib.
访问它,为什么不为需要所有其他库的每个文件夹编写一个init.lua
文件呢
例如,在计算中,您编写的文件包含
return {
calc1 = require "calc1";
calc2 = require "calc2";
calc3 = require "calc3";
}
然后您可以只编写calculations=require“calculations”
,它将自动加载计算。calc
这可以对整个目录结构执行,并且require“helper”
可以调用require“help1”
,这反过来调用require“print”
,最后您可以在helper.help1.print中找到您的函数。
简要说明其工作原理:当您运行require“library”
时,lua将尝试包含名为library.lua的文件或位于library
目录中的文件init.lua
。这也是为什么需要“dir.lib”
而不是需要“dir/lib”
的原因;因为,如果操作正确,当您只需要“dir”
时,它将返回一个包含字段lib
的表,因此您可以作为dir.lib来访问它。
该模块部分实现了您想要的功能,尽管它还远远不够完美
它允许分组/命名导入,但有一些注意事项-主要是您必须手动管理您的环境。此外,您还需要编写索引文件(默认init.lua
,除非您编写自定义路径集),因为它用于导出表的模块
这里有一个例子。首先,我们需要正确设置文件结构
-- main.lua
-- calculations /
-- calc1.lua
-- calc2.lua
-- calc3.lua
-- init.lua
-- helper /
-- print /
-- init.lua
-- graphprinter.lua
-- matrixprinter.lua
索引文件有点乏味:
-- calculations/init
return {
calc1 = require 'calculations.calc1',
calc2 = require 'calculations.calc2',
calc3 = require 'calculations.calc3'
}
及
在主文件中。主要的警告很快就会显现出来,您必须使用通过要求'env'
返回的函数来覆盖您的本地环境。不传递任何参数将创建当前环境的克隆(保留require
等)
新环境将被赋予一个函数,该函数接受一个参数,一个字符串表示要导入当前环境的路径或模块名。返回值是一个临时表,可用于进一步更改环境状态
import 'helper/print' :use '*'
import 'calculations' :use '*'
瞬态表上的一个函数是:use
,它要么获取一个表,指示要从所需表中提取哪些值,要么获取字符串“*”
,指示要将所需表中的所有值放置在当前环境中
print(matrixprinter, graphprinter) --> function: 0x{...} function: 0x{...} (or so)
最后一点需要注意的是,您看到的所有路径都依赖于与包含main.lua
的路径相同的路径lua myapp/main.lua
将大声失败,除非您将子模块放置在静态位置,并正确调整package.path
/import.path
要避免几行require
语句,似乎需要做很多工作
免责声明:我写这篇文章只是一个小小的实验
请注意,import
当前不支持
语法(您需要使用操作系统路径分隔符),也不支持将表正确分解为表链。我在工作中有一个补丁来解决这个问题
Lua 5.2+使用\u ENV
覆盖本地环境。对于Lua5.1,您需要使用
如上所述,Lua没有真正的目录概念。要真正做到您想要的(以较少的开销),您需要编写自己的自定义模块加载器、环境处理程序,并且可能需要使用一个模块来可靠地“自动”加载目录中的所有文件
TL;博士:
- 这是一个棘手的话题
- 语言中没有任何东西可以让这变得简单
- 你需要写一些定制的东西
- 总会有缺点
该模块部分实现了您想要的功能,但还远远不够完美
它允许分组/命名导入,但有一些注意事项-主要是您必须手动管理您的环境。此外,您还需要编写索引文件(默认init.lua
,除非您编写自定义路径集),因为它用于导出表的模块
这里有一个小问题
import 'helper/print' :use '*'
import 'calculations' :use '*'
print(matrixprinter, graphprinter) --> function: 0x{...} function: 0x{...} (or so)