让模块访问父脚本中的 Local

Letting modules access a Local in the parent script

更新:

一些进一步的阅读 (local variable cannot be seen in a closure across the file?) 让我 "aha!" 时刻明白了为什么我的代码不起作用。

在Lua中,local x对同一范围内的任何事物都是可见的-同一函数中的事物,if/then结构,for循环,其他从该函数等调用的函数,但 不是 其他模块,即使它们是从本地范围内调用的。我没有找到比 "because reasons" 更好的解释,但仅仅知道模块是 "normal" 范围行为的例外至少让我放心。

原文post:

(非常抱歉,如果有这个问题的答案;我已经用谷歌搜索了几个小时,结果很短。)

我已经为我喜欢的音频软件 (Reaper) 编写了一个 GUI 库。在 recording/playback 期间,脚本很有可能成为 运行,因此性能是一个大问题,我正在尝试尽可能将所有内容保留在本地。总的来说很简单,但是在脚本中使用 GUI 库 + 元素 类 时我遇到了一些麻烦。

主要 GUI 模块:

-- Core.lua --

local function GUI_table()
  local GUI = {}

  -- Template for GUI elements
  GUI.Element = {}
  function GUI.Element:new(name)
    local elm = {}
    setmetatable(elm, self)
    self.__index = self
    return elm
  end

  ...add a bunch of GUI.do_this = function()....

  return GUI

  end
GUI = GUI_table()

所有 GUI 元素都是相同形式的单独文件:

-- Class - Button.lua --

if not GUI then throw_a_missing_library_error_and_quit end

GUI.Button = GUI.Element:new()
function GUI.Button:draw()
...etc...

我目前正在通过 loadfile("Core.lua")() 从父脚本加载它们。这工作得很好,但它将 GUI 放在全局 table 中,并带有相关的查找开销。到目前为止,试图重写一些东西以便 GUI 可以是本地的,但进展并不顺利。我试过:

local GUI
loadfile("Core.lua")()
loadfile("Class - Button.lua")()
...

失败,因为主脚本的 GUI 调用都转到本地 _GUI,但加载的文件由于作用域无法看到或添加到其中。

loadfile("Core.lua")()
loadfile("Class - Button.lua")()
local GUI = GUI

运行良好,但在性能方面没有影响:模块代码中的错误仍然可以追溯到模块(即 "line 23 in Class - Button.lua"),这让我假设模块仍然在它们自己的范围内我的本地 GUI 实际上并没有被触及。

我也试过 Core.lua return GUI table 直接,所以主脚本可以有 local GUI = loadfile("Core.lua")(),但是我 运行 遇到了麻烦,无法让元素模块访问它,如上所述。我知道,范围界定。

那么,考虑到以上所有情况,是否有一种 "correct" 方法来 write/structure 模块,以便一切都在本地 GUI 中结束?我得到的印象是已失效的 module(..., package.seeall) 功能会解决这个问题......也许不会。

干杯。

这是循环依赖的问题。我注意到 ElementButton 进入 内部 GUI,但它们不 依赖 GUI为了他们的建设。将 Element 放入其自己的文件中将允许您将所有内容都放在本地。

-- Core.lua --

local GUI = {}

-- Template for GUI elements
GUI.Element = require 'Element'

GUI.Button = require 'Button'

return GUI

-- Element.lua --

return {
  new = function(self, name)
    local elm = {}
    setmetatable(elm, self)
    self.__index = self
    return elm
  end,
}

-- Class - Button.lua --

Button = require('Element'):new()
function Button:draw()
end

return Button