Модель _ENV в Lua 5.2+
Изучите, как _ENV заменил setfenv и обеспечивает управление окружением.
«Модель _ENV в Lua 5.2+» — бесплатный урок Lua Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Что такое _ENV
В Lua 5.2 и новее каждый фрагмент кода имеет неявную внешнюю переменную с именем _ENV. Все обращения к глобальным переменным переписываются как обращения к полям _ENV. Поэтому print(x) преобразуется в _ENV.print(_ENV.x).
_ENV заменяет setfenv
В Lua 5.1 функция setfenv(fn, env) изменяла глобальное окружение функции. В версиях 5.2 и новее этот механизм удалён. Вместо этого объявите _ENV локальной переменной, чтобы изменить окружение фрагмента кода или блока.
Изменение _ENV во фрагменте кода
Задайте _ENV в начале фрагмента кода, чтобы перенаправить все обращения к глобальным переменным.
-- Everything in this chunk uses myEnv as globals
local _ENV = myEnv
print("hello") -- calls myEnv.print("hello")Локальный _ENV для блока
Ограничьте область действия изменений _ENV блоком do...end, чтобы уменьшить их влияние.
do
local _ENV = {print = print, x = 42}
print(x) -- 42 from local _ENV
end
print(x) -- original _ENV.x (global x)Использование load с _ENV
load(chunk, chunkname, mode, env) выполняет строку как фрагмент кода с пользовательским окружением. Это основной механизм создания песочницы в версиях 5.2 и новее.
local env = {print = print, math = math}
local fn, err = load("print(math.sqrt(16))", "sandbox", "t", env)
if fn then fn() end -- 4.0Чтение текущего _ENV
Глобальные переменные текущего фрагмента кода находятся в _ENV. Чтобы получить ссылку на него: local myEnv = _ENV.
Изменение _ENV во время выполнения
Установка глобальной переменной выполняется как _ENV.varName = value. Поскольку _ENV является внешней переменной, в любой момент выполнения можно заменить его другой таблицей.
Наследование с помощью __index
Задайте окружению песочницы метатаблицу с __index = _G, чтобы использовать настоящую глобальную таблицу как запасной вариант для функций, которые Вы явно не заблокировали.
local sandboxEnv = setmetatable({}, {__index = _G})
-- then block dangerous ones:
sandboxEnv.os = nil
sandboxEnv.io = nil
sandboxEnv.load = nilОбнаружение попыток доступа к _ENV
Замените опасные глобальные переменные специальным маркером, который регистрирует попытки доступа для аудита безопасности.
sandboxEnv.os = setmetatable({}, {
__index = function(_, k)
ngx.log(ngx.WARN, "Blocked access: os." .. k)
return nil
end
})Примечание о совместимости
Библиотеки, использующие setfenv/getfenv из Lua 5.1, необходимо переписать для версии 5.2 и новее. Некоторые из них используют адаптер совместимости в коде инициализации.
Практическое значение
Модель _ENV делает создание песочницы более простым и последовательным. Для окружений существует один понятный механизм вместо двух: setfenv для функций и глобальные переменные для верхнего уровня.
Вопрос об _ENV
Как Lua 5.2 и новее переписывает обращение к глобальной переменной print(x)?
Итоги: модель _ENV
Lua 5.2 и новее направляет все обращения к глобальным переменным через внешнюю переменную _ENV. Используйте load(code, name, "t", env), чтобы выполнить код в пользовательском окружении. Это стандартный механизм создания песочницы, заменяющий setfenv.
Часто задаваемые вопросы
Урок «Модель _ENV в Lua 5.2+» бесплатный?
Да — полный текст урока «Модель _ENV в Lua 5.2+» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Модель _ENV в Lua 5.2+»?
Изучите, как _ENV заменил setfenv и обеспечивает управление окружением. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Модель _ENV в Lua 5.2+»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Модель _ENV в Lua 5.2+
- Создание ограниченной песочницы
- Предотвращение выхода из песочницы
- Ограничения ресурсов и инструментирование