Lua: setfenv() против _ENV

В чем большая проблема с переключением Lua от setfenv() до _ENV?

В разных источниках "Что нового" этот шаг упоминается как одно из наиболее важных изменений между версиями Lua 5.1 и 5.2.

Однако примеры, приведенные в PIL и в других местах, можно обрезать до следующих значений:

-- Lua 5.1                   -- Lua 5.2
function myfunc()            function myfunc()
    setfenv(1, {})               _ENV = {}
end                          end

До сих пор мы получили то, что мы сохранили пять ключевых штрихов. (Я считаю, что ситуация не сильно отличается от стороны C.) Более того, если бы я понял, что setfenv() может использоваться как извне, так и изнутри функции, тогда как _ENV может быть доступен только из внутри функции. (Разумеется, при использовании C API можно получить доступ к upvalues ​​напрямую.) Из того, что я написал, подход 5.2 выглядит гораздо менее гибким.

В своем Новинках Lua 5.2 Роберто пишет:

"Будучи синтаксическим сахаром, он намного проще, чем старые среды"

Где простота? Что я пропустил?

Я считаю, что эта тема заслуживает лучшего лечения, которое дано в Руководстве пользователя 5.2.

Ответ 1

Где простота?

Это зависит от того, как вы определяете "простоту".

В Lua 5.1 окружающая среда была волшебной, мистической установкой, которая была непохожа на любые другие настройки в системе. У него не было явного места, и его можно было установить только с помощью стандартных функций библиотеки.

В Lua 5.2 среда является переменной, как и любая другая. Он имеет имя, которое вы можете использовать. Так что проще в том, что более очевидно, что происходит.

Кроме того, в Lua 5.1, среда функции может быть изменена динамически.

В Lua 5.2, вне прямой обработки upvalue, как только функция имеет среду, то есть окружение, которое будет иметь бесконечность. Окружение для функции наследуется, лексически охвачено как обычная переменная local. Поэтому, если вы посмотрите на свой код, вы можете легко увидеть, в какой среде находится функция. Если в области создания этой функции нет local _ENV, тогда среда должна быть средой куска (которая определяется load).

Ответ 2

Насколько я могу судить, основным недостатком сред Lua 5.2 является то, что они не могут быть установлены снаружи, т.е. вы не можете сказать setfenv(func, {}). Это, на мой взгляд, огромная неудача. Это действительно проще, чем среды Lua 5.1, но не в хорошем смысле.