Lua:有关本地作用域的模块导入。

有两个脚本文件,具体如下所示

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

    require "child"  
end  

//child.lua
print(var)

这样,child.lua 将打印一个空值,因为 parent.lua 中的作用域不会将其局部特性暴露给模块。我认为会这样,因为 require 指令在此作用域内声明 var 之后。我的意愿是将 child 的所有行几乎全部注入 parent 中。 child 脚本只是为了更好的可读性而导出。如何传递局部作用域? loadfile() 不起作用,dofile() 也不起作用。函数环境 fenv 不包含局部值。debug.setlocal() 似乎无法创建新变量(它还需要在 child 中接收器)。有没有除重新编译脚本之外的方法?

点赞
用户1442917
用户1442917

你可以通过一点努力做到这一点。如果 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 中也是可行的。

2013-05-23 23:22:51