1

Lua を埋め込み、スクリプトがグローバル テーブルを読み取れるようにするが、自動的に書き込むことはできないようにしたいので、2 つのスクリプトが同じ名前の変数を書き込めるようにします。これよりもうまく説明することはできません:

スクリプト 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;
}
4

2 に答える 2

3

__indexあなたが変わりたいのではなく、それは__newindex. さらに__index、テーブルに存在するキーへのアクセスをキャッチするために使用することはできません。すべての状況でテーブルを読み取り専用にする唯一の方法は、すべての読み取りをプロキシ テーブルに任せ、書き込み時にエラーをスローすることです。

于 2011-08-22T10:33:01.367 に答える
2

読み取り専用テーブルを返すために使用する関数を次に示します。

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

これは再帰的には機能しないことに注意してください。そのため、テーブルがグローバル (または組み込み関数のいずれか) として定義されている場合、内容は変更できますが、テーブル自体を置き換えることはできません。

于 2011-08-22T11:52:42.550 に答える