2013-05-23 16 views
5

aşağıdaki komutlua: Yerel kapsamı ile ilgili modül ithalat parent.lua içinde kapsamı yerel özelliklerini göstermiyor olmasıdır

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

    require "child" 
end 

//child.lua 
print(var) 

Bu şekilde iki komut dosyaları vardır, child.lua bir nil değerini yazdırır Modüle Gereksinim yönergesinin bu kapsamda ve var beyanından sonra belirtileceğini düşündüm. Benim arzum, çocuğun tüm satırlarını tamamen ebeveyne enjekte etmektir. Altyazı, daha iyi okunabilirlik için gönderilmiştir. Yerel kapsamı nasıl geçebilirim? loadfile() işe yaramadı, dofile(). Fonksiyon ortamı fenv yerel değerleri barındırmaz. debug.setlocal() yeni değişkenler oluşturamaz gibi gözüküyor (ayrıca çocukta bir alıcı gerektiriyor). Komut dosyasını yeniden derlemenin yanında herhangi bir yöntem var mı?

+0

Hayır, bu Lua 5.1'de mümkün değildir. Lua 5.2'de 'debug.upvaluejoin' kullanarak bu etkiyi veren bir korsanlık var. – finnw

+2

Ne 'require' ne de' dofile ', Lua'da olmayan 'include' ile aynıdır. – lhf

+0

Çocuk yazılarınızı neden argüman alma işlevi olarak yeniden yazmıyorsunuz? –

cevap

1

Biraz çaba ile yapabilirsiniz. child'daki değişkenleriniz gerçek upvalde'lerinizse, bunları scope işlevinizdeki değerlere "bağlayabilirsiniz". Küresel değişkenlerse (burada durum böyle görünüyor), bunları setfenv kullanarak bir ortama eşleştirebilir ve bu ortamı yerel değişkenlerinizden değerlerle doldurabilirsiniz.

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() 

Bu Lua 5.1 için tüm, ama Lua 5.2 de mümkündür:

Eğer (aynı etkiye sahip loadfile için loadstring değiştirebilirsiniz) beklediğiniz gibi şu abc yazdırılır.