2012-06-11 2 views
0

У меня есть код lua в файле. Я хочу создать несколько экземпляров закрытия этого кода, каждый из которых имеет значение _ENV. Я могу использовать luaL_loadfile для загрузки файла и установки первого upvalue, N раз с разными таблицами, для создания N экземпляров. Но не будет ли это загружать и компилировать файл N раз?Lua создать несколько экземпляров закрытия

Lua эквивалент того, что я хочу сделать, это следующее, за исключением без LoadFile

func_list = {} 

for i = 1, 10 do 
    local new_env = {hello=i, print=print} 
    func_list[i] = loadfile("Code.lua", "t", new_env) 
end 

for i = 1, 10 do 
    func_list[i]() 
end 

------ Code.lua ------ 
print(hello*hello) 

есть лучший способ сделать это?

ответ

1

Всякий раз, когда вы загружаете строку/файл в Lua, что вы получаете взамен есть функция для вызова на самом деле запустить файл. То, что load делает для вас, является лишь некоторой дополнительной обработкой, чтобы установить _ENV.

Тем не менее, ничто не мешает вам установить _ENV самостоятельно. Вы можете сделать это с чем-то вроде этого:

-- Code.lua -- 
_ENV = ... 
print(hello * hello) 

Затем вы можете загрузить/скомпилировать файл только один раз, и использовать несколько экземпляров, как например:

local code = loadfile("Code.lua") 

env_list = {} 
for i = 1, 10 do 
    local new_env = {hello=i, print=print} 
    code(new_env) 
    env_list[i] = new_env 
end 

Если вы не хотите, чтобы пользователь напишите _ENV = ... в каждом файле, вы можете вместо этого загрузить файл в строку, добавьте строку самостоятельно и используйте load для компиляции источника. Но это не сработало бы на скомпилированных файлах.

+0

Вы имели в виду 'code (new_env); func_list [i] = new_env' в цикле for. – z33m

+0

Кроме того, вместо добавления '_ENV = ...' в код. Предложение DeadMG также должно работать правильно? то есть. установив первое upvalue на new_env перед выполнением chunk – z33m

+0

Спасибо за комментарий, я исправил это. Что касается второго вопроса, вы можете использовать [эту реализацию 'setfenv' для Lua 5.2] (http://lua-users.org/lists/lua-l/2010-06/msg00313.html), чтобы получить то, что вы хотите. Просто обратите внимание, что теперь у вас есть только одно закрытие, которое меняет свою среду, а не многократное закрытие. –

1

Используйте библиотеки ввода-вывода, чтобы загрузить файл в строку, а затем наберите loadstring.

В качестве альтернативы, просто получить один кусок, а затем изменить его окр до выполнения его

+0

Если я использую 'loadstring', он будет компилировать код каждый раз, правильно? – z33m

+0

@ z33m: Да, но по крайней мере вам не придется выполнять ввод-вывод. Невозможно дублировать фрагмент Lua после его компиляции. – Puppy

Смежные вопросы