如何在lua中运行一个字符串并获取它创建的变量的所有表格?

所以我正在创建自己的LIKO-12操作系统,我需要运行.lk12文件,但我需要一个函数来运行字符串作为代码并返回一个返回代码创建的所有变量的表格

示例:

function foo()
        return "Hello,"
end

function bar()
        return " World!"
end

hello = foo()..bar()

应返回一个具有2个函数的表格: 一个名为foo的函数,其返回"Hello," 一个名为bar的函数,返回" World!" 还有一个名为hello的变量,它具有"Hello,World!"

您应该能够使用vars ["foo"]()vars.foo()从代码中调用函数

有人可以帮我吗?

点赞
用户106104
用户106104

当你创建或使用全局变量时,它实际上是存储在一个名为“环境”或_ENV的表中(它不是全局的,它是一个自动获取的局部变量)

所以你的代码:

function foo()
        return "Hello,"
end

function bar()
        return " World!"
end

hello = foo()..bar()

其实是这样的:

function _ENV.foo()
        return "Hello,"
end

function _ENV.bar()
        return " World!"
end

_ENV.hello = _ENV.foo().._ENV.bar()

因此,如果我们将 _ENV 设置为一个新表,并将其返回,那么这正是你想要的表。你可以使用 load(用于运行字符串)来实现这一点,将其作为第四个参数传递。此函数将执行此操作:

function loadAndReturnEnv(codeString)
    local env = {}
    load(codeString, nil, nil, env)() -- 在演示中跳过错误检查
    return env
end

但是,请注意,所有常规的全局函数,如 string.reptable.sortloadprint 都不存在于这个新代理环境中。如果你想这样,那很好。但是我想你可能确实需要它们。在这种情况下,我们可以使用元表的 __index 功能,使得如果代码在自己的 _ENV 中查找而找不到东西,它会在我们的(调用者的)_ENV 中查找。

function loadAndReturnEnvWithGlobals(codeString)
    -- 注意:env 是我们将要运行的代码的环境
    -- (在该代码中将被称为 _ENV),而 _ENV 是 loadAndReturnEnvWithGlobals 函数的环境
    --(即,“真正的”环境)
    local env = {}
    setmetatable(env, {__index=_ENV})
    load(codeString, nil, nil, env)() -- 在演示中跳过错误检查
    setmetatable(env, nil) -- 在返回之前将表设置为正常状态
    return env
end

等等...现在运行程序时,程序可以调用 print ,但是如果它定义了一个函数,那么该函数不能调用 print ,因为我们在代码返回后删除了指向真正环境的链接。因此,我认为修复这个问题的最佳方法是保留环境之间的链接,并只复制函数等。

function loadAndReturnEnvWithGlobals2(codeString)
    local env = {}
    setmetatable(env, {__index=_ENV})
    load(codeString, nil, nil, env)() -- 在演示中跳过错误检查

    local result = {}
    for k,v in pairs(env) do result[k]=v end
    return result
end

虽然这会复制值,因此如果你有任何更改变量的函数,你将看不到更改的变量。

你使用哪个版本取决于你。它们各有优缺点。

2021-08-16 15:41:09