2013-05-23 9 views
5

Ci sono due file di script con il seguente scriptlua: modulo di importazione per quanto riguarda ambito locale

//parent.lua 
function scope() 
    local var = "abc" 

    require "child" 
end 

//child.lua 
print(var) 

In questo modo, child.lua stamperà un valore pari a zero in quanto il campo di applicazione in parent.lua non espone le sue caratteristiche locali al modulo. Ho pensato che sarebbe, dal momento che la direttiva di richiesta è dichiarata all'interno di questo ambito e dopo la dichiarazione di var. Il mio desiderio è di iniettare praticamente tutte le linee del bambino nel genitore. Lo script figlio è appena esportato per una migliore leggibilità. Come posso passare l'ambito locale? loadfile() non ha funzionato, né ha fatto dofile(). La funzione ambiente fenv non contiene valori locali. debug.setlocal() non sembra in grado di creare nuove variabili (inoltre richiederebbe un ricevitore nel figlio). Qualche metodo oltre a ricompilare lo script?

+0

No, questo non è possibile in Lua 5.1. C'è un hack che può dare questo effetto in Lua 5.2, usando 'debug.upvaluejoin'. – finnw

+2

Né '' require' né dofile' è uguale a 'include', che non esiste in Lua. – lhf

+0

Perché non si riscrive lo script figlio come una funzione che riceve argomenti? –

risposta

1

È possibile con un po 'di sforzo. Se le tue variabili in child sono valori up reali, puoi "collegarli" a valori nella tua funzione scope. Se sono variabili globali (che sembra essere il caso qui), puoi associarle ad un ambiente usando setfenv e popolare quell'ambiente con i valori delle tue variabili locali.

Quanto segue stampa abc come ci si aspetterebbe (si può cambiare loadstring-loadfile con lo stesso effetto):

function vars(f) 
    local func = debug.getinfo(f, "f").func 
    local i = 1 
    local vars = {} 
    while true do 
    local name, value = debug.getlocal(f, i) 
    if not name then break end 
    if string.sub(name, 1, 1) ~= '(' then vars[name] = value end 
    i = i + 1 
    end 
    i = 1 
    while func do -- check for func as it may be nil for tail calls 
    local name, value = debug.getupvalue(func, i) 
    if not name then break end 
    vars[name] = value 
    i = i + 1 
    end 
    return vars 
end 

function parent() 
    local var = "abc" 

    local child = loadstring("print(var)") 

    local env = vars(2) -- grab all local/upvalues for the current function 
    -- use these values to populate new environment; map to _G for everything else 
    setmetatable(env, {__index = _G}) 
    setfenv(child, env) 

    child() 
end 

parent() 

Questo è tutto per Lua 5.1, ma è anche possibile in Lua 5.2.

Problemi correlati