2011-04-08 6 views
15

मैं निम्नलिखित कोड है कहते हैं:क्लोजर फ़ंक्शन के लिए मैं गतिशील रूप से मेटाडेटा कैसे ढूंढूं?

 
(defn ^{:graph-title "Function 1"} func-1 
    [x] 
    (do-something-with x)) 

(defn get-graph-title 
    [func] 
    (str 
    ((meta func) :graph-title))) 

मैं इस वापसी करने की उम्मीद "समारोह 1", लेकिन यह नहीं के बराबर देता है।

 
(meta func-1) 
=> {:ns some-ns-info, :name func-1} 
(meta #'func-1) 
=> {:ns some-ns-info, :name func-1, :graph-title "Function 1"} 

किसी ने मुझे इस व्याख्या कर सकते हैं: मैं इस निम्नलिखित अंतर है, जो मैं पूरी तरह समझ नहीं है की वजह से उपजी लगता है?

उत्तर

18

मेटाडेटा कार्य से नहीं, var से जुड़ा हुआ है।

इस प्रकार, ग्राफ शीर्षक प्राप्त करने के लिए, आपको var के मेटा से प्रविष्टि :graph-title प्राप्त करना होगा। आप अपने मैक्रोज़ को कैसे पसंद करते हैं?

(defmacro get-graph-title 
    [func] 
    `(:graph-title (meta (var ~func)))) 

(get-graph-title func-1) 
=> "Function 1" 
+4

या बस वर्तमान परिभाषा का उपयोग करें और करें (गेट-ग्राफ-शीर्षक # 'func-1) –

2

मेटाडाटा आप अपने स्रोत कोड में प्रतीक समारोह -1 के समय इसका उल्लेख वर डीईएफ़ विशेष रूप से समारोह -1 नामित को कॉपी किया है। http://clojure.org/special_forms

जब आप का मूल्यांकन func-1 जहां कि एक प्रतीक एक वर के लिए बाध्य है में डीईएफ़ के लिए दस्तावेज़ देखें, तो आप वर की मूल्य (जो इस मामले में समारोह वस्तु है) मिलता है। देखें http://clojure.org/vars

फ़ंक्शन ऑब्जेक्ट स्वयं प्रतीक/var पर मैन्युअल रूप से निर्दिष्ट मेटाडेटा प्राप्त नहीं करता है।

तो, जो जानकारी आप चाहते हैं वह बिल्कुल कार्य में नहीं है। यह var में है, और आपको यह निर्दिष्ट करना होगा कि आप वास्तव में इसके मूल्य के बजाय var func-1 स्वयं चाहते हैं। यही है (var func-1), और समकक्ष शॉर्ट-कट # 'func-1 करता है।

30

वहाँ प्रतीक'func-1 पर समारोहfunc-1 पर मेटाडाटा, वार#'func-1 पर मेटाडाटा, और मेटाडाटा है। क्लोजर रीडर मैक्रो ^ रीड टाइम पर प्रतीक पर मेटाडेटा जोड़ता है। defnप्रतीक से Var पर संकलन समय पर मैक्रो प्रतियां मेटाडेटा।

क्लोजर 1.2 से पहले, फ़ंक्शन मेटाडेटा का समर्थन नहीं करते थे। Clojure 1.2 में, वे करते हैं, और defn भी प्रतियां कुछ मानक वारसमारोह मेटाडाटा:

Clojure 1.2.0 
user=> (defn ^{:foo :bar} func-1 [] nil) 
#'user/func-1 
user=> (meta func-1) 
{:ns #<Namespace user>, :name func-1} 
user=> (meta #'func-1) 
{:foo :bar, :ns #<Namespace user>, :name func-1, ... 

हालांकि, मौजूदा Clojure 1.3 स्नैपशॉट में, defn कोई मेटाडेटा कार्य करने के लिए नकल नहीं करता है:

Clojure 1.3.0-master-SNAPSHOT 
user=> (defn ^{:foo :bar} func-1 [] nil) 
#'user/func-1 
user=> (meta func-1) 
nil 
user=> (meta #'func-1) 
{:foo :bar, :ns #<Namespace user>, :name func-1, ... 

सामान्य रूप से, यदि आप किसी परिभाषा के मेटाडेटा में जाना चाहते हैं, तो आप Var पर मेटाडेटा चाहते हैं।

+0

लियोनेल का जवाब जो मैं ढूंढ रहा था उसके करीब था, लेकिन स्पष्टीकरण के लिए धन्यवाद - चीजों को बहुत साफ करता है। – funkymunky

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

  • कोई संबंधित समस्या नहीं^_^