仅允许全球环境访问(Lua)
我嵌入了Lua,希望脚本能够读取全局表,但不会自动写入,这样两个脚本就可以使用相同的名称写入变量,而不会相互覆盖,但仍然能够向全局表添加内容。我真的无法更好地解释这一点: 脚本1仅允许全球环境访问(Lua),lua,luaj,Lua,Luaj,我嵌入了Lua,希望脚本能够读取全局表,但不会自动写入,这样两个脚本就可以使用相同的名称写入变量,而不会相互覆盖,但仍然能够向全局表添加内容。我真的无法更好地解释这一点: 脚本1 var1 = "foo" _G.var2 = "bar" 脚本2 print(var1) -- Prints nil print(var2) -- Prints 'bar' 我是如何做到这一点的(脚本是一个函数) 我的Lua绑定是LuaJ,为了在这里提供所有信息,代码也是: private LuaValue new
var1 = "foo"
_G.var2 = "bar"
脚本2
print(var1) -- Prints nil
print(var2) -- Prints 'bar'
我是如何做到这一点的(脚本是一个函数)
我的Lua绑定是LuaJ,为了在这里提供所有信息,代码也是:
private LuaValue newScript(String content){
LuaTable envMt = new LuaTable();
envMt.set(INDEX, _G);
LuaTable env = new LuaTable();
env.setmetatable(envMt);
LuaClosure func = (LuaClosure) _G.get("loadstring").call(valueOf(content));
thread = new LuaThread(func,env);
thread.resume(NIL);
return thread;
}
您要更改的不是
\uuu索引
,而是\uu新索引
。此外,您不能使用\uu index
捕获对表中确实存在的键的访问。使表在所有情况下均为只读的唯一方法是将所有读取延迟到代理表,并在写入时抛出错误。您要更改的不是\uuu index
,而是\uu newindex
。此外,您不能使用\uu index
捕获对表中确实存在的键的访问。在所有情况下使表成为只读的唯一方法是将所有读取延迟到代理表,并在写入时抛出错误。以下是我用于返回只读表的函数:
function ro_table (t)
local t = t
if t then
return setmetatable({},
{ __index=t,
__newindex= function(_,_,_) error ("Attempt to modify read-only table") end,
})
else
return nil
end
end
因此,对于您的代码,您将具有以下内容:
newScript = function(content)
Script = loadstring(content)()
setfenv(Script,ro_table(_G))
return Script
end
请注意,这不会递归工作,因此,如果您有任何定义为全局的表(甚至任何内置函数),则可以更改内容,但不能替换表本身。以下是我用于返回只读表的函数:
function ro_table (t)
local t = t
if t then
return setmetatable({},
{ __index=t,
__newindex= function(_,_,_) error ("Attempt to modify read-only table") end,
})
else
return nil
end
end
因此,对于您的代码,您将具有以下内容:
newScript = function(content)
Script = loadstring(content)()
setfenv(Script,ro_table(_G))
return Script
end
请注意,这不是递归工作的,因此如果您有任何定义为全局的表(甚至任何内置函数),则可以更改内容,但不能替换表本身