setfenv
Lua 5.2 での機能を再現するにはどうすればよいですか? _ENV
新しい環境変数の使用方法を正確に理解するのに苦労しています。
Lua 5.1 ではsetfenv
、任意の機能を非常に簡単にサンドボックス化できます。
--# Lua 5.1
print('_G', _G) -- address of _G
local foo = function()
print('env', _G) -- address of sandbox _G
bar = 1
end
-- create a simple sandbox
local env = { print = print }
env._G = env
-- set the environment and call the function
setfenv(foo, env)
foo()
-- we should have global in our environment table but not in _G
print(bar, env.bar)
この例を実行すると、次の出力が表示されます。
_G table: 0x62d6b0
env table: 0x635d00
nil 1
この簡単な例を Lua 5.2 で再現したいと思います。以下は私の試みですが、上記の例のようには機能しません。
--# Lua 5.2
local function setfenv(f, env)
local _ENV = env or {} -- create the _ENV upvalue
return function(...)
print('upvalue', _ENV) -- address of _ENV upvalue
return f(...)
end
end
local foo = function()
print('_ENV', _ENV) -- address of function _ENV
bar = 1
end
-- create a simple sandbox
local env = { print = print }
env._G = env
-- set the environment and call the function
foo_env = setfenv(foo, env)
foo_env()
-- we should have global in our envoirnment table but not in _G
print(bar, env.bar)
この例を実行すると、次の出力が表示されます。
upvalue table: 0x637e90
_ENV table: 0x6305f0
1 nil
load
この件に関して他にもいくつか質問があることは承知していますが、それらのほとんどは、Lua 5.2 で提供され
た新しい機能を使用して非常にうまく機能する動的コード (ファイルまたは文字列) のロードを扱っているようです。ここでは、サンドボックスで任意の関数を実行するためのソリューションを具体的に求めています。debug
ライブラリを使用せずにこれを行いたいと思います。Lua のドキュメントによると、Luaに依存する必要はありません。