module - lua:关于本地范围的模块导入

标签 module lua scope embed local

有两个脚本文件,脚本如下

//parent.lua
function scope()
    local var = "abc"

    require "child"
end

//child.lua
print(var)

这样,child.lua 将打印一个 nil 值,因为 Parent.lua 中的范围不会向模块公开其本地功能。我认为会的,因为 require 指令是在这个范围内并且在 var 声明之后声明的。我的愿望是将子代的所有行几乎完全注入(inject)到父代中。子脚本只是为了更好的可读性而导出。我怎样才能传递本地范围? loadfile() 不起作用,dofile() 也不起作用。函数环境 fenv 不包含本地值。 debug.setlocal() 似乎无法创建新变量(它还需要子级中的接收器)。除了重新编译脚本还有什么方法吗?

最佳答案

只要付出一点努力就可以。如果 child 中的变量是真正的上值,您可以将它们“链接”到 scope 函数中的值。如果它们是全局变量(这里似乎是这种情况),您可以使用 setfenv 将它们映射到环境,并使用本地变量中的值填充该环境。

以下内容将按照您的预期打印 abc (您可以将 loadstring 更改为 loadfile ,效果相同):

function vars(f)
  local func = debug.getinfo(f, "f").func
  local i = 1
  local vars = {}
  while true do
    local name, value = debug.getlocal(f, i)
    if not name then break end
    if string.sub(name, 1, 1) ~= '(' then vars[name] = value end
    i = i + 1
  end
  i = 1
  while func do -- check for func as it may be nil for tail calls
    local name, value = debug.getupvalue(func, i)
    if not name then break end
    vars[name] = value
    i = i + 1
  end
  return vars
end

function parent()
  local var = "abc"

  local child = loadstring("print(var)")

  local env = vars(2) -- grab all local/upvalues for the current function
  -- use these values to populate new environment; map to _G for everything else
  setmetatable(env, {__index = _G})
  setfenv(child, env)

  child()
end

parent()

这都是 Lua 5.1 的内容,但在 Lua 5.2 中也是可能的。

关于module - lua:关于本地范围的模块导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16715401/

相关文章:

将 Lua 文件对象转换为 C 文件*

lua - 吉他英雄般的计时机制

javascript - 循环const,图的let声明...如何修复?

c++ - 错误: ‘calloc’ was not declared in this scope

javascript - Javascript/jquery 中的范围和/或点击监听器问题

swift - 从 Swift 模块导入一个类

javascript - ember + 找不到模块 `@ember/application`

c++ - Windows/C++ : why are loaded module memory bytes changing at run-time?

java - 如何使用 Java 程序加载/卸载 Linux 内核模块?

lua - lua 和 walk_block 中的 pandoc 过滤器