【问题标题】:How to make global variables "immutable" in Lua/LuaJ?如何在 Lua/LuaJ 中使全局变量“不可变”?
【发布时间】:2023-03-05 22:18:01
【问题描述】:

说明

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

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

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

例如,这是脚本 1:

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

这是脚本 2:

foo();

做了什么

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

LuaJ How to avoid overriding existing entries in Globals table

Preventing Function Overriding in Lua Table

Making global environment access-only (Lua)


我尝试在每次执行脚本时加载 lib,或设置 local _ENV,但由于可能有进一步的从 Java 到 Lua 的回调,它无法正常工作。

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

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

效果很好,但成本很高。有没有更好的办法?

【问题讨论】:

    标签: lua luaj readonly-variable


    【解决方案1】:

    我假设您想保护三个函数不被覆盖: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
    })
    

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

    -- the script 1:
    foo1 = function()
       print("bar");
    end
    foo1();   -- original protected.foo1() is invoked
    
    -- the script 2:
    foo1();   -- original protected.foo1() is invoked
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-01
      • 2021-12-11
      • 1970-01-01
      • 2012-04-20
      • 2014-01-31
      • 2018-05-09
      • 2017-03-05
      • 1970-01-01
      相关资源
      最近更新 更多