2011-10-25 33 views
5

Eğer bu çok açıksa özür dilerim ama ben tamamen yeni bir kullanıcıyım ve referansta bulamıyorum.Lua'da bir işlev verilen bir işlev var mı, adını bir dize olarak döndürüyor mu?

Lua'da bir NAME_OF_FUNCTION işlevi var mı, bir işlev verildiğinde bana bir tablo ekleyebilmem için bir ad veriliyor mu?

local M = {} 

local function export(...) 
    for x in ... 
    M[NAME_OF_FUNCTION(x)] = x 
    end 
end 

local function fun1(...) 
... 
end 

local function fun2(...) 
... 
end 

. 
. 
. 

export(fun1, fun2, ...) 

return M 
+0

Sadece kendim dışa aktarmak için dizgeyi geçebilirdim, ama sorduğumu düşündüm çünkü func'in kendisinden daha zarif olduğunu düşünüyorum. Kaynağında olduğu gibi isminden beri çok zor olmasına rağmen, sadece kaynakta yaşar. – Paralife

+1

Bence bu noktada yanılıyorsunuz 'kaynakta olduğu gibi sadece kaynakta yaşıyor '. Bu, çoğu statik ve derlenmiş diller için geçerlidir, ancak dinamik/komut dosyası dilleri isimlerini arayarak işlevleri gönderir, böylece geç bağlama yapabilirler (ve maymun yama koduna vb. Işlevlerini yeniden eklemelerine izin verebilirler) – fortran

+1

olası bir kopyası [ Lua'daki nesne ismini dizginle] (http://stackoverflow.com/questions/6800648/stringify-object-name-in-lua) – finnw

cevap

5

Böyle bir işlev yoktur. İşlevler birinci sınıf vatandaşlar olduğu için böyle bir işlev yok sanırım. Yani bir işlev, değişken tarafından atıfta bulunulan, diğerleri gibi bir değerdir. Bu nedenle, NAME_OF_FUNCTION işlevinin işlevi çok kullanışlı olmaz; çünkü aynı işlevin ona işaret eden çok sayıda değişkeni olabilir veya hiç yoktur.

Genel işlevler veya tablodaki işlevler için (isteğe bağlı veya _G), değerin x değerine eşit olup olmadığını kontrol ederek bir tablodaki işlevleri taklit edebilirsiniz. Eğer öyleyse fonksiyon ismini buldunuz.

fun1={ 
    fun=function(self,...) 
     print("Hello from "..self.name) 
     print("Arguments received:") 
     for k,v in pairs{...} do print(k,v) end 
    end, 
    name="fun1" 
} 
fun_mt={ 
    __call=function(t,...) 
     t.fun(t,...) 
    end, 
    __tostring=function(t) 
     return t.name 
    end 
} 
setmetatable(fun1,fun_mt) 
fun1('foo') 
print(fun1) -- or print(tostring(fun1)) 

Bu çıplak işlevleri nedeniyle kullanarak biraz daha yavaş olacaktır:

a=function() print"fun a" end 
b=function() print"fun b" end 
t={ 
    a=a, 
    c=b 
} 
function NameOfFunctionIn(fun,t) --returns the name of a function pointed to by fun in table t 
    for k,v in pairs(t) do 
     if v==fun then return k end 
    end 
end 
print(NameOfFunctionIn(a,t)) -- prints a, in t 
print(NameOfFunctionIn(b,t)) -- prints c 
print(NameOfFunctionIn(b,_G)) -- prints b, because b in the global table is b. Kind of a NOOP here really. 

başka bir yaklaşım, bir tablodaki işlevleri kaydırmak ve MetaTable böyle, işlevini çağırır kurmak zorunda olacaktır Metatable arama. Ve herhangi bir kişinin durumdaki ismin ismini değiştirmesini, onu içeren tablodaki işlevin adını değiştirmesini, işlevi değiştirmeyi, vb. Tabloyu, bir modül olarak dışa aktarırsanız iyi olabilen fun1.fun gibi dizinleri de bölebilirdiniz, ancak metata ekleyebileceğiniz ad ve diğer hileleri kaybedersiniz.

+0

Fonksiyonun bir değer olması doğrudur, ancak bu, bir bileşenin değeri olamaz, işlevin kodu ve onunla ilişkili meta veriler olarak bir ad olması anlamına gelmez. Bunu sadece Lua yoludur anlıyorum: tanımlanmış her fonksiyon tuşu ile bir tabloda saklanan bir lambda olduğuna fonksiyon tanımı isimleri: " fonksiyon f() vücut uç f çevirir açıklamada = function() gövde sonu ", Lua referansı – Paralife

+2

uyarınca, ancak bu anahtarın bir dize olması gerekmez. Lua'da aşağıdakiler tamamen doğrudur: t = {[function() print'foo 'end] = function() print'bar'end, {} = function() print'baz'end} 'Burada anahtarlar sırasıyla fonksiyonlar ve tablolar. Bu, tablonun diğer fonksiyonları değil, fonksiyonları içerdiğini söyledi. Meta veriyi bir işleve ekleyebilirsiniz, ancak her zaman "verdiğim örneklerde olduğu gibi dışsal olacaktır. Lua'da, bir işlev bir bileşik değer değil, yalnızca Lua'nın izin veren araçları teslim etme felsefesine uyar – jpjacobs

+0

bir şey inşa ve doğru eklemek için başka bir şeyim yok :) – Paralife

0

bu deneyin: Bunu istiyorum Sebep Böyle bir şey yapmak istiyorum olmasıdır

http://pgl.yoyo.org/luai/i/tostring

toString (x) umarım

+1

Bunun işe yaradığı konusunda şüpheliydim, bu yüzden denedim, ve öyle görünmüyor: http://codepad.org/uaZ2zSXW – delnan

+0

Ah, kuşkusuz ki birazcık var sayıyordum .. :( – Hybrid

+0

string.format da işe yaramıyor .. Uygun bir format seçeneği yok gibi görünüyor ... – Paralife

0

Eğer aradığınızı olmalıdır Yanlış değilim (ve muhtemelen, çünkü Lua'da hiç programlamamıştım, sadece bir sürü makale ve makale okudum), dahili olarak fonksiyon isimlerine sahip bir tablo var (Python'da locals ve globals gibi), Bu nedenle, hangi anahtarın bir işlev referansı ile eşleştiğini görmek için geriye doğru arama yapabilmeniz gerekir. Her neyse, sadece spekülasyon yapıyor.

Ama gerçek şu ki, kodunuza bakarak zaten fonksiyonların adını biliyorsunuz, bu yüzden tabloyu oluşturmakta özgürsünüz. Daha az hataya yatkın olmak istiyorsanız, işlev referansını (eval veya bunun gibi bir şeyle) almak için işlev adını kullanmak daha kolay olacaktır.

+0

Haklısın. Ama içine kazandıktan sonra, en yakın şey debug.getinfo işlevidir.Ama isim dönmez. global tablo, yerel fonksiyonlardan bahsetmiyor.Ama nesneden bir isim elde etmek için bir iç gözlem yolunu arıyorum ya da söylediğin gibi, başka bir şekilde: adından gelen bir nesne. Ancak, şimdiye kadar hiç şans yok – Paralife

+1

Bir fonksiyon değeri birçok ada sahip olabilir, ya da yok. – lhf

1

Teknik olarak bu mümkün, burada ihracat() fonksiyonunun bir uygulaması var:

function export(...) 
     local env = getfenv(2); 
     local funcs = {...}; 
     for i=1, select("#", ...) do 
       local func = funcs[i]; 
       for local_index = 1, math.huge do 
         local local_name, local_value = debug.getlocal(2, local_index); 
         if not local_name then 
           break; 
         end 
         if local_value == func then 
           env[local_name] = local_value; 
           break; 
         end 
       end 
     end 
     return env; 
end 

Bu Lua 5.2 için bazı değişiklikler gerektirecektir, debug API kullanır ve nihayet mutlaka bir olarak uygun bulmuyorum Modüller yazmak için iyi bir yol, sadece soruya tam anlamıyla cevap veriyorum.

İlgili konular