で失敗するのに対し、一度に1つずつ。私のクイッククイックテストでは、5.1と5.2の両方が変更なしにサンドボックスの外で定義された関数を実行します。あなたがいなかったので、上記の両方の例では、display
関数はそのコードに変更を加えることなくprint
を使用していることを
-- 5.1
local function display(...)
print(...)
end
local script = loadstring "display(math.log(2, 3))"
local env = {display = display, math = math, string = string}
setfenv(script, env)
print(pcall(script))
-- 5.2
local function display(...)
print(...)
end
local script = loadstring "display(math.log(2, 3))"
local e=_ENV
_ENV={display = display, math = math, string = string}
e.print(e.pcall(script))
_ENV=e
注:Dougの例を使用するには、display
はprint
を使用して、あなたの既存のコードの一部であると仮定この関数が作成されたときのサンドボックス内の
以前は、サンドボックス環境ではない場所へのポインタを格納していましたが、クイッククイックテストで必要な状況を再現することはできません。例を考え出すことができたら、おそらくe
変数を必要としない回避策を考え出すことができます。ここでは5.2を使用して、そのコードの例です:
local e=_ENV
for k,v in e.pairs(value) do
-- iterate
end
別の例として、私は唯一のテーブルコードを読み取るために、私は再びe
を使用しています:
function ro_table (t)
local t = t
if t then
return e.setmetatable({},
{ __index=t,
__newindex= function(_,_,_) e.error ("Attempt to modify read-only table") end,
})
else
return nil
end
end
これは私が望むものに近いようです。私はそれを試して、それが私が必要とする方法で動作するかどうかを見ていきます。 –