lua: module import regarding local scope

夙愿已清 提交于 2019-12-12 10:53:45

问题


There are two script files with the following script

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

    require "child"
end

//child.lua
print(var)

This way, child.lua will print a nil value because the scope in parent.lua does not expose its local features to the module. I thought it would, since the require directive is stated within this scope and after the declaration of var. My desire is to practically wholly inject all the lines of the child into the parent. The child script is just exported for better readability. How can I pass the local scope? loadfile() did not work, nor did dofile(). The function environment fenv does not harbor local values. debug.setlocal() does not seem to be able to create new variables (also it would require a receiver in the child). Any method besides recompiling the script?


回答1:


You can with a bit of effort. If your variables in child are real upvalues you can "link" them to values in your scope function. If they are global variables (which seems to be the case here), you can map them to an environment using setfenv and populate that environment with values from your local variables.

The following will print abc as you'd expect (you can change loadstring to loadfile with the same effect):

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()

This is all for Lua 5.1, but it's also possible in Lua 5.2.



来源:https://stackoverflow.com/questions/16715401/lua-module-import-regarding-local-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!