lua:关于本地范围的模块导入 [英] lua: module import regarding local scope

查看:196
本文介绍了lua:关于本地范围的模块导入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有两个带有以下脚本的脚本文件

There are two script files with the following script

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

    require "child"
end

//child.lua
print(var)

这样,child.lua将打印一个nil值,因为parent.lua中的作用域不会向模块公开其本地功能.我以为会这样,因为require指令是在此范围内并且在var声明之后声明的.我的愿望是实际上将孩子的所有血统注入到父母中.子脚本只是导出以提高可读性.如何通过本地范围? loadfile()无效,dofile()也无效.功能环境fenv不包含局部值. debug.setlocal()似乎无法创建新变量(也需要在子代中使用接收器).除了重新编译脚本,还有其他方法吗?

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?

推荐答案

您可以稍作努力.如果child中的变量是真实的上值,则可以将它们链接"到scope函数中的值.如果它们是全局变量(在这里似乎是这种情况),则可以使用setfenv将它们映射到环境,并使用局部变量中的值填充该环境.

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.

以下内容将按您期望的方式打印abc(您可以将loadstring更改为loadfile,具有相同的效果):

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

这一切都适用于Lua 5.1,但在Lua 5.2中也是可能的.

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

这篇关于lua:关于本地范围的模块导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆