加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 程序设计 > 正文

创建一组相互依赖的Lua文件,而不会影响全局命名空间

发布时间:2020-05-23 00:11:03 所属栏目:程序设计 来源:互联网
导读:tl; dr:什么设计模式允许您将Lua代码分割为多个文件,这些文件需要在不影响全局表的情况下共享某些信息? 背景 在Lua中创建库需要库影响全局命名空间被认为是不好的形式: -- somelib.lua --SomeLib = { ... }-- usercode.lua --require somelibprint(SomeLib

tl; dr:什么设计模式允许您将Lua代码分割为多个文件,这些文件需要在不影响全局表的情况下共享某些信息?

背景

在Lua中创建库需要库影响全局命名空间被认为是不好的形式:

--> somelib.lua <--
SomeLib = { ... }

--> usercode.lua <--
require 'somelib'
print(SomeLib) -- global key created == bad

相反,最好的做法是创建一个使用局部变量的库,然后返回它们以供用户根据需要进行分配:

--> somelib.lua <--
local SomeLib = { ... }
return SomeLib

--> usercode.lua <--
local theLib = require 'somelib' -- consumers name lib as they wish == good

使用单个文件时,上述模式工作正常.但是,当您有多个相互引用的文件时,这会变得相当困难.

具体例子

如何重写以下文件套件以使断言全部通过?理想情况下,重写将在磁盘上保留相同的文件,并为每个文件保留责任. (通过将所有代码合并到单个文件中进行重写是有效的,但没有帮助;)

--> test_usage.lua <--
require 'master'

assert(MASTER.Simple)
assert(MASTER.simple)
assert(MASTER.Shared)
assert(MASTER.Shared.go1)
assert(MASTER.Shared.go2)
assert(MASTER.Simple.ref1()==MASTER.Multi1)
assert(pcall(MASTER.Simple.ref2))
assert(_G.MASTER == nil)                   -- Does not currently pass
--> master.lua <--
MASTER = {}
require 'simple'
require 'multi'
require 'shared1'
require 'shared2'
require 'shared3'
require 'reference'

--> simple.lua <--
MASTER.Simple = {}
function MASTER:simple() end

--> multi.lua <--
MASTER.Multi1 = {}
MASTER.Multi2 = {}

--> shared1.lua <--
MASTER.Shared = {}

--> shared2.lua <--
function MASTER.Shared:go1() end

--> shared3.lua <--
function MASTER.Shared:go2() end

--> reference.lua <--
function MASTER.Simple:ref1() return MASTER.Multi1 end
function MASTER.Simple:ref2() MASTER:simple()      end

失败:设置环境

我想通过自我引用将环境设置为主表来解决问题.但是当调用require这样的函数时,这不起作用,因为它们会改变环境:

--> master.lua <--
foo = "original"
local MASTER = setmetatable({foo="captured"},{__index=_G})
MASTER.MASTER = MASTER
setfenv(1,MASTER)
require 'simple'

--> simple.lua <--
print(foo)         --> "original"
MASTER.Simple = {} --> attempt to index global 'MASTER' (a nil value)
你给master.lua两个职责:

>它定义了通用模块表
>它导入所有子模块

相反,您应该为(1)创建一个单独的模块并将其导入所有子模块:

--> common.lua <--
return {}

--> master.lua <--
require 'simple'
require 'multi'
require 'shared1'
require 'shared2'
require 'shared3'
require 'reference'
return require'common' -- return the common table

--> simple.lua <--
local MASTER = require'common' -- import the common table
MASTER.Simple = {}
function MASTER:simple() end

等等

最后,更改test_usage.lua的第一行以使用局部变量:

--> test_usage.lua <--
local MASTER = require'master'
...

测试现在应该通过.

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读