2012-09-19 25 views
6

निम्नलिखित मान लें,अभिव्यक्ति जो क्लोजर में वर्तमान में सभी स्कॉप्ड प्रतीकों को लौटाती है?

(in-ns silly.fun) 

(def a 1) 

(defn fx [b] 
    ((fn [c] (return-all-symbols)) (first b))) 

अगर यह एक वापसी-सभी प्रतीकों समारोह है कि प्रतीकों में से नक्शा वापसी होगी संभव है मैं सोच रहा था/मूल्यों वर्तमान में अपने मंगलाचरण पर scoped। तो, मान लीजिए कि उपर्युक्त संकलित किया गया था और हम 'मूर्ख' नामस्थान में थे, हम निम्नलिखित की तरह कुछ चला सकते थे।

(fx [:hello]) => {"a" 1, "b" [:hello], "c" :hello} 

मैं डिबगिंग उद्देश्यों के लिए रिटर्न-ऑल-प्रतीकों का उपयोग करना चाहता हूं। क्या सब कुछ संभवतः वापसी-सब-प्रतीक है? यदि हां, तो इसका कार्यान्वयन क्या है?

उत्तर

8

यह संभव है, लेकिन जैसा कि आपने इसे परिभाषित किया है, आप बहुत दुखी होंगे: आप एक नक्शा नहीं चाहते हैं जिसमें सैकड़ों प्रविष्टियां clojure.core में सभी कार्यों का जिक्र करती हैं! और यहां तक ​​कि यदि आप केवल वर्तमान नामस्थान में देखते हैं, तो आप fx को शामिल करना भूल गए हैं, जो एक प्रतीक है जिसका मूल्य एक कार्य है। इसके अलावा मैक्रोज़ द्वारा पेश किए जाने वाले लेक्सिकल प्रतीकों को अक्सर आप नहीं चाहते हैं। उदाहरण के लिए, (let [[x y] foo]) चार प्रतीकों को उपलब्ध दिखाएगा: foo, x, y, और vec__auto__4863 जैसे कुछ।

वैसे भी, आपको शायद उन मुद्दों पर कुछ समझौता करना होगा, और अन्य (और वास्तव में मुझे लगता है कि यह बेहतर है) निर्दिष्ट करें कि आप वास्तव में कौन से प्रतीकों का नक्शा चाहते हैं।

(defmacro return-all-symbols [] 
    (let [globals (remove (comp :macro meta val) (ns-publics *ns*)) 
     syms (mapcat keys [globals, &env]) 
     entries (for [sym syms] 
        [`(quote ~sym) sym])] 
    `(into {} 
      (for [[sym# value#] [[email protected]] 
       :when (not (fn? value#))] 
      [sym# value#])))) 


(def a 1) 

(defn fx [b] 
    ((fn [c] (return-all-symbols)) (first b))) 

(fx [:hello]) 
;=> {a 1, c :hello, b [:hello]} 
+1

कुछ समय वास्तव में आप क्या किया के माध्यम से पार्स करने के लिए ले जा रहा है, लेकिन मैं इसे करने की कोशिश की और यह काम करने लगता है। रंग मुझे प्रभावित किया। –

2

नेमस्पेस में वर्तमान में स्कॉप्ड वर्रों के साथ एक नक्शा शामिल है, जो आपको इच्छित चीज़ों का हिस्सा देता है। हालांकि यह (let [x 4] (return-all-symbols)) की तरह भाव से lexicaly scoped प्रतीकों को याद अभी भी डीबगिंग के लिए उपयोगी हो सकता है जाएगा:

core> (take 2 (ns-map *ns*)) 
([sorted-map #'clojure.core/sorted-map] [read-line #'clojure.core/read-line]) 

यदि आप इस से अधिक की आवश्यकता है तो आप एक असली डिबगर जावा डिबगिंग इंटरफ़ेस का उपयोग करता है की आवश्यकता हो सकती। the clojure debugging toolkit

2

(ns-interns) हो सकता है: लेकिन स्वचालित रूप से उन प्रतीकों जो या तो कर रहे हैं (क) शाब्दिक या (ख) वर्तमान नाम स्थान में परिभाषित किया गया है, और भी (ग) एक समारोह से मैप नहीं, तो आप इस्तेमाल कर सकते हैं के लिए मूल्यों को प्राप्त करने के लिए आप क्या चाहते हैं, लेकिन (lazy-seq) में लिपटे बड़े नामस्थान के लिए अच्छा काम करता है।

1 (ns-map 'clojure.core) 
2 {sorted-map #'clojure.core/sorted-map, read-line #'clojure.core/read-line, re-pattern #'clojure.core/re-pattern, keyword? #'clojure.core/keyword?, ClassVisitor clojure.asm.ClassVisitor, asm-type #'clojure.core/asm-type, val #'clojure.core/val, ...chop...}