2015-10-13 3 views
3

Итак, у меня есть сценарий Lua, в котором я устанавливаю среду функции и определяю другие функции, которые я предоставляю в среде. Проблема в том, что когда я вызываю функцию, которую я сделал setfenv, любая функция, которую он вызывает в среде, использует глобальную среду _G для значений поиска, а не для среды, которую я устанавливал при вызове начальной функции. Я копировал проблему ниже:Окружения Lua при вызове функции в функции setfenv

> function f() print(t) end 
> t = 5 
> f() 
5 
> env = {} 
> env['print'] = print 
> env['t'] = 7 
> env['f'] = f 
> setfenv(f, env) 
> f() 
7 
> setfenv(f, _G) 
> f() 
5 
> function g() f() end 
> g() 
5 
> setfenv(g, env) 
> g() 
5 

Есть ли способ, чтобы получить среду для распространения на все вызовы без необходимости делать setfenv на каждой функции я хочу добавить к env (в основном, так что последний призыв в пример к g() вернет 7 вместо 5)?

Использование Lua 5.1.

+0

Функциональные среды в Lua 5.1 не наследуются при вызове функции (вам нужно вручную вызвать 'setfenv' перед вызовом этой функции для решения вашей проблемы). Новая система окружающей среды (начиная с 5.2, используя _ENV) делает возможным правильное наследование. –

+0

Невозможно воспроизвести это поведение в 5.1? – Ford

ответ

1

Вы можете написать функцию, чтобы она автоматически изменяет свою собственную среду при каждом вызове

-- This code works on Lua 5.1, 5.2, 5.3 
local getfenv = getfenv or function() end 
local setfenv = setfenv or getfenv 

a = 1 

function f(env) 
    local _ENV = env or getfenv(2) or _ENV; setfenv(1, _ENV) 
    print(a) 
end 

env = { a = 2, print = print } 

-- inherit environment for this call 
f() --> 1 
-- set special environment for this call 
f(env) --> 2 
f() --> 1 

setfenv(1, getfenv(2)) Или просто, если вы работаете только с Lua 5.1 и хотите всегда наследуют окружение.