1

描述

我正在做一个 LuaJ 程序,这是一个这样的 lib 脚本:

function foo()
    print("foo");
end

我希望该foo函数可以在其他脚本中直接调用(否require),但在不同的脚本中执行不可变。(即使脚本会覆盖它,它也会以其他脚本中的原始方式执行。)

例如,这是脚本 1:

foo = function()
    print("bar");
end

这是脚本2:

foo();

做了什么

我看到了这两个问题。他们确实有效,但不是解决这个问题的方法。

LuaJ 如何避免覆盖全局表中的现有条目

防止 Lua 表中的函数覆盖

使全局环境只能访问(Lua)


我尝试在每次 exec 脚本或 set 时加载 lib local _ENV,但是因为可能有从 Java 到 Lua 的进一步回调,所以它不能正常工作。

Globals我现在通过每次在 Java 中加载脚本时创建一个并加载 lib 脚本来处理它,如下所示:

    public static void main(String[] args) {
        loadAndCallViaDifferentEnv(libPath, script1);
        loadAndCallViaDifferentEnv(libPath, script2);
    }

    static void loadAndCallViaDifferentEnv(String libPath, String scriptPath) {
        Globals globals = JsePlatform.standardGlobals();
        globals.loadfile(libPath).call();
        globals.loadfile(scriptPath).call();
    }

它运作良好,但成本很高。有没有更好的办法?

4

1 回答 1

3

我假设您想保护三个函数不被覆盖foo1foo2print

-- define foo1 and foo2 inside protected table instead of as usual globals
local protected = {}

function protected.foo1()  
   print("foo1");
end

function protected.foo2()
   print("foo2");
end

-- if a function to be protected already exists, remove it from globals:
protected.print = print
print = nil

-- Now set the metatable on globals
setmetatable(_G, {
   __index = protected,
   __newindex =
      function(t, k, v)
         if not protected[k] then
            rawset(t, k, v)
         end
      end
})

现在您可以在没有 的情况下从其他模块调用foo1,但不能覆盖它们:foo2printrequire

-- the script 1:
foo1 = function()
   print("bar");
end
foo1();   -- original protected.foo1() is invoked
-- the script 2:
foo1();   -- original protected.foo1() is invoked
于 2021-06-01T03:27:12.007 回答