使全局环境仅可访问(Lua)
我嵌入了 Lua 并希望脚本能够读取全局表但不能自动写入它,因此两个脚本可以写入具有相同名称的变量而不会互相覆盖,但仍然能够向全局表添加内容。我真的无法比这更好地解释它:
脚本 1
var1 = "foo"
_G.var2 = "bar"
脚本 2
print(var1) -- Prints nil
print(var2) -- Prints 'bar'
我如何尝试通过执行类似这样的操作来完成此任务(“脚本”是一个函数)
newScript = function(content)
Script = loadstring(content)()
env = setmetatable({},{__index = _G})
setfenv(Script,env)
return Script
end
我的 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;
}
I embedded Lua and want scripts to be able to read the global table but not automatically write to it so two scripts can write variables with the same name without overwriting eachother but still being able to add stuff to the global table. I can't really explain it better then this:
Script 1
var1 = "foo"
_G.var2 = "bar"
Script 2
print(var1) -- Prints nil
print(var2) -- Prints 'bar'
How I tried to accomplish this is by doing something like this (The 'scripts' being a function)
newScript = function(content)
Script = loadstring(content)()
env = setmetatable({},{__index = _G})
setfenv(Script,env)
return Script
end
My Lua binding is LuaJ, for the sake of giving all information here is that code too:
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您要更改的不是
__index
,而是__newindex
。此外,您不能使用__index
来捕获对表中确实存在的键的访问。在所有情况下使表只读的唯一方法是将所有读取推迟到代理表并在写入时抛出错误。It's not
__index
that you want to change, it's__newindex
. In addition, you can't use__index
to catch access to keys that do exist in the table. The only way to make a table read-only in all situations is to defer all reads to a proxy table and throw an error on writes.这是我用来返回只读表的函数:
因此,对于您的代码,您将具有以下内容:
请注意,这不会递归地工作,因此如果您有任何定义为全局的表(或者甚至是任何内置的表), -in 函数)内容可以更改,但表本身不能替换。
Here's a function I use to return a read-only table:
So for your code, you'd have the following:
Note that this does not work recursively, so if you have any table defined as a global (or even any of the built-in functions) the contents can be changed, but the table itself cannot be replaced.