0Pricing
Lua Academy · Урок

Модель _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 — локальная установка не требуется.

Все уроки этого курса

  1. Модель _ENV в Lua 5.2+
  2. Создание ограниченной песочницы
  3. Предотвращение выхода из песочницы
  4. Ограничения ресурсов и инструментирование
← Назад к Lua Academy