2011-10-25 20 views
5

क्षमा करें अगर यह बहुत स्पष्ट है, लेकिन मैं लुआ के लिए कुल नवागंतुक हूं, और मुझे संदर्भ में यह नहीं मिल रहा है।लुआ में, क्या कोई फ़ंक्शन है जो फ़ंक्शन देता है, यह उसका नाम स्ट्रिंग के रूप में देता है?

वहाँ लुआ में एक NAME_OF_FUNCTION समारोह है कि एक समारोह को देखते हुए मुझे इतना है कि मैं सूचकांक इसके साथ एक मेज कर सकते हैं इसका नाम देता है?

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

मैं सिर्फ अपने आप को निर्यात करने के लिए स्ट्रिंग पारित सकता है, लेकिन मैंने सोचा था कि क्योंकि मुझे लगता है कि यह समारोह अपने आप में गुजर अधिक सुरुचिपूर्ण है मैं पूछ होगी। यद्यपि यह स्रोत के रूप में नाम के बाद बहुत भिन्न है, केवल स्रोत में ही रहता है। – Paralife

+1

मुझे लगता है कि आप इस बिंदु में गलत हैं क्योंकि नाम स्रोत में है केवल स्रोत में रहता है। यह सबसे स्थिर और संकलित भाषाओं के लिए सच है, लेकिन गतिशील/पटकथा भाषाएं उनके नामों को देखकर कार्यों को प्रेषित करती हैं, इसलिए वे देर से बाध्यकारी हो सकते हैं (और बंदर पैच कोड इत्यादि में कार्यों को पुन: स्थापित करने की अनुमति देते हैं) – fortran

+1

संभावित डुप्लिकेट [ लुआ में ऑब्जेक्ट का नाम स्ट्रिंग करें] (http://stackoverflow.com/questions/6800648/stringify-object-name-in-lua) – finnw

उत्तर

5

वहां ऐसा कोई फ़ंक्शन नहीं है। मुझे लगता है कि ऐसा कोई कार्य नहीं है, क्योंकि कार्य प्रथम श्रेणी के नागरिक हैं। तो एक फंक्शन वैरिएबल द्वारा संदर्भित किसी भी अन्य की तरह एक मूल्य है। इसलिए NAME_OF_FUNCTION फ़ंक्शन बहुत उपयोगी नहीं होगा, क्योंकि एक ही फ़ंक्शन में कई चर हो सकते हैं, या कोई भी नहीं।

आप, टेबल (मनमाने ढंग से या _G) के माध्यम से पाशन पता चल सके कि मान x बराबर वैश्विक काम करता है, या किसी तालिका में कार्यों के लिए एक का अनुकरण कर सकते हैं। यदि ऐसा है तो आपको फ़ंक्शन का नाम मिल गया है।

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. 

एक और दृष्टिकोण एक तालिका में कार्यों लपेट, और एक metatable सेट अप फ़ंक्शन को कॉल करने, इस तरह के लिए होगा:

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

इसमें कुछ समय नंगे कार्यों क्योंकि का उपयोग कर की तुलना में धीमी हो जाएगा मेटाटेबल लुकअप का। और यह किसी को भी राज्य में फ़ंक्शन का नाम बदलने, उसमें मौजूद तालिका में फ़ंक्शन का नाम बदलने, फ़ंक्शन बदलने आदि को रोकने से नहीं रोकेगा, इसलिए यह सबूत छेड़छाड़ नहीं है। आप fun1.fun जैसे अनुक्रमणित करके टेबल की पट्टी भी पट्टी कर सकते हैं जो कि यदि आप इसे मॉड्यूल के रूप में निर्यात करते हैं तो अच्छा हो सकता है, लेकिन आप नामकरण और अन्य चाल को हटा सकते हैं जिन्हें आप मेटाटेबल में डाल सकते हैं।

+0

फ़ंक्शन के मूल्य के बारे में सही है, लेकिन इसका मतलब यह नहीं है कि यह एक कंपाउंड वैल्यू नहीं हो सकता है, जिसमें फ़ंक्शन का कोड और उसके साथ जुड़े मेटाडेटा नाम हो। मैं समझता हूँ कि यह सिर्फ लुआ तरीका है: हर कार्य परिभाषित सिर्फ एक लैम्ब्डा कुंजी के साथ एक तालिका में संग्रहीत है कि समारोह परिभाषा के नाम: "बयान समारोह च() शरीर अंत को च तब्दील = function() बॉडी एंड "के अनुसार, लूआ संदर्भ – Paralife

+2

सत्य के अनुसार, लेकिन उस कुंजी को स्ट्रिंग नहीं होना चाहिए। निम्नलिखित लूआ में पूरी तरह से सही है: 't = {[function() print'foo 'end] = function() print'bar'end, {} = function() print'baz'end}' तो यहां कुंजी हैं क्रमशः कार्यों और तालिकाओं। उस ने कहा, तालिका में कार्य शामिल हैं, न कि दूसरी तरफ। आप किसी फ़ंक्शन में मेटाडेटा संलग्न कर सकते हैं, लेकिन यह हमेशा "बाहरी, जैसा कि मैंने दिए गए उदाहरणों में किया होगा। लुआ में, एक समारोह एक यौगिक मूल्य नहीं है, यह केवल कार्य है, जैसा कि लुआ के औजारों को सौंपने के दर्शन को फिट करता है कुछ भी बनाना – jpjacobs

+0

सच है, और मेरे पास जोड़ने के लिए और कुछ नहीं है :) – Paralife

0

इस प्रयास करें:: कारण मैं यह चाहता हूँ कि मैं इस तरह कुछ करना चाहता हूँ है

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

toString (एक्स) उम्मीद है कि होना चाहिए आप के लिए

+1

किसी तरह से विलय किया जा सकता है, मुझे संदेह था कि यह काम करता है, इसलिए मैंने कोशिश की, और ऐसा लगता है कि यह नहीं है: http://codepad.org/uaZ2zSXW – delnan

+0

ओह, माना जाता है कि मैं थोड़ा सा अनुमान लगा रहा था .. :( – Hybrid

+0

string.format भी काम नहीं करता है। कोई उपयुक्त प्रारूप विकल्प प्रतीत नहीं होता है ... – Paralife

0

तो क्या देख रहे मैं गलत नहीं हूँ (और मैं शायद होगा, क्योंकि मैं वास्तव में लुआ में कभी नहीं प्रोग्राम किया, बस के कागजात और लेख की एक गुच्छा पढ़ें), आंतरिक रूप से पहले से ही समारोह के नाम के साथ एक मेज है (जैसे locals और globals अजगर में), तो आप यह देखने के लिए एक रिवर्स-लुकअप करने में सक्षम होना चाहिए कि फ़ंक्शन संदर्भ से कौन सी कुंजी मेल खाती है।

वैसे भी, सिर्फ अटकलें।

लेकिन वास्तव अपने कोड को देखते हुए, आप पहले से ही कार्यों का नाम जानते हैं, तो आप तालिका का निर्माण करने के लिए स्वतंत्र हैं कि है। यदि आप कम त्रुटि प्रवण होना चाहते हैं, तो फ़ंक्शन संदर्भ प्राप्त करने के लिए फ़ंक्शन के नाम का उपयोग करना आसान होगा (eval या उसके जैसा कुछ) अन्य तरीकों से।

+0

आप सही हैं। लेकिन इसमें खोदने के बाद, सबसे नज़दीकी चीज़ जो मैं प्राप्त कर सकता हूं वह debug.getinfo फ़ंक्शन है। लेकिन यह नाम वापस नहीं करता है। इसके अलावा _G वैश्विक तालिका स्थानीय कार्यों का उल्लेख नहीं करती है। मैं अभी भी ऑब्जेक्ट से नाम प्राप्त करने के लिए एक आत्मनिरीक्षण पथ खोज रहा हूं, या जैसा आपने कहा था, दूसरी तरफ: नाम से ऑब्जेक्ट। लेकिन अब तक कोई भाग्य नहीं है। – Paralife

+1

एक फ़ंक्शन वैल्यू कई नाम हो सकते हैं, या कोई नहीं। – lhf

1

तकनीकी तौर पर यह संभव है, यहां निर्यात() फ़ंक्शन के एक कार्यान्वयन है:

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 

यह debug API का उपयोग करता है, लुआ 5.2 के लिए कुछ परिवर्तन की आवश्यकता होगी, और अंत में मैं जरूरी एक के रूप में यह समर्थन नहीं करते मॉड्यूल लिखने का अच्छा तरीका, मैं सिर्फ सचमुच सवाल का जवाब दे रहा हूं।

संबंधित मुद्दे

 संबंधित मुद्दे