Я учусь на «Программировании в Lua» Роберто Ирусалимши, и я обнаружил, что в книге в примере песочницы используется функция setfenv()
для изменения окружения данной функции, но в lua 5.2 эта функция больше недоступна.
Я попытался загрузить некоторые значения из файла (файла конфигурации) в поле таблицы, но в lua 5.2 я не могу использовать setfenv (поэтому я могу загружать значения в данной среде). Прочитав несколько статей о lua 5.2, я обнаружил, что каждая функция может иметь (или не иметь) повышающее значение, называемое _ENV, которое служит средой, поэтому я попробовал следующий код:
function sandbox(sb_func, sb_env)
if not sb_func then return nil, "sandbox function not valid" end
sb_orig_env = _ENV
_ENV = sb_env -- yes, replaces the global _ENV
pcall_res, message = pcall( sb_func )
local modified_env = _ENV -- gets the environment that was used in the pcall( sb_func )
_ENV = sb_orig_env
return true, modified_env
end
function readFile(filename)
code = loadfile(filename)
res, table = sandbox(code, {})
if res then
--[[ Use table (modified_env) ]]--
else
print("Code not valid")
end
Замена _ENV
в функции «песочницы» работает хорошо (не может получить доступ к обычным полям), но, когда «код» выполняется, кажется, что он игнорирует замену _ENV
, он по-прежнему может получить доступ к обычным полям (print, loadfile, dofile и т. д.).
Прочитав немного больше, я обнаружил, что lua 5.2 предоставляет функцию для этой цели, это функция loadin(env, chunk)
, которая запускает данный фрагмент в данной среде, но, когда я пытаюсь добавить эту функцию в свой код, функция не работает. существует (отсутствует в глобальном поле _G
).
Некоторая помощь будет оценена по достоинству.