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, но не в хорошем смысле.