Description
I'm doing a LuaJ program, and here's a lib script like this:
function foo()
print("foo");
end
I want the foo
function can be invoked in other scripts directly (no require
), but performs immutable in different scripts. ( Even a script overrides it, it performs as the original way in other scripts. )
For example, here's the script 1:
foo = function()
print("bar");
end
and here is the script 2:
foo();
What's done
I have saw these two questions. They do work but not the solution to this problem.
LuaJ How to avoid overriding existing entries in Globals table
Preventing Function Overriding in Lua Table
Making global environment access-only (Lua)
I tried loading lib every time exec a script, or set local _ENV
, but because there may be further callbacks from Java to Lua, it doesn't work correctly.
I now handle it by create a Globals
and load lib script every time load a script in Java like this:
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();
}
It works well, but costs much. Is there a better way?
I assume you want to protect three functions from overwriting: foo1
, foo2
and print
-- 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
})
Now you can invoke foo1
, foo2
and print
from other modules without require
, but you can not overwrite them:
-- the script 1:
foo1 = function()
print("bar");
end
foo1(); -- original protected.foo1() is invoked
-- the script 2:
foo1(); -- original protected.foo1() is invoked