2012-07-31 13 views
5

पर उपनाम बनाना मेरे पास एक नामस्थान में कुछ निजी फ़ंक्शन हैं जिन्हें मैं दूसरे नामस्थान में शामिल करना चाहता हूं। जैसेकिसी अन्य क्लोजर नेमस्पेस

(ns one) 

(defn ^:private foo 
    "A docstring" 
    [x] (* x 2)) 

और दूसरा नाम स्थान इस के लिए एक उपनाम बनाएं करने की जरूरत है:

(ns two) 

(def foo ???) 

(foo 3) ;; should work as if the function in namespace one was called 
=> 6 

आदर्श रूप में मैं docstring संरक्षित करने के लिए तो मैं दो स्थानों पर इसे बनाए रखने की जरूरत नहीं है चाहता हूँ। इसके अलावा मैं या तो एक ही नाम या एक अलग नाम का उपयोग करने का विकल्प चाहता हूं।

इस आवश्यकता का कारण निम्नानुसार है: कार्यक्षमता की आवश्यकता है/नामस्थान one में उपयोग की जाती है। onetwo की निर्भरता है, और चूंकि हमारे पास परिपत्र निर्भरता नहीं हो सकती है, इसलिए foo को two के भीतर परिभाषित करने के लिए यह काम नहीं करेगा। two सार्वजनिक एपीआई है, इसलिए foo को two नामस्थान का सार्वजनिक रूप से हिस्सा होना चाहिए।

इसे प्राप्त करने का सबसे अच्छा तरीका क्या है?

+0

आप अन्य नाम एक ही होना चाहते हैं या यह कुछ भी हो सकता है? – Ankur

+0

@ अंकुर - वर्तमान में एक ही नाम का उपयोग करना चाहते हैं, लेकिन कुछ मामलों में यह एक अलग नाम के साथ उपनाम बनाने के लिए भी उपयोगी हो सकता है, इसलिए समाधान के लिए यह अच्छा होगा। – mikera

+0

इसे आज़माएं: '(def foo (with-meta one/foo (मेटा # 'एक/foo))) – Ankur

उत्तर

5

कैसे इस बारे में:

(ns one) 

(defn- foo 
    "A docstring" 
    [x] (* x 2)) 

(ns two) 

(def foo-alias #'one/foo) 
(alter-meta! #'foo-alias merge (select-keys (meta #'one/foo) [:doc :arglists])) 

चाल प्रतीक 'एक/foo का समाधान नहीं है, इसलिए इसकी मेटाडाटा पर निजी ध्वज को गति प्रदान करने से परहेज है। फिर अपने दूसरे नामस्थान में fi aliasing के बाद, आप केवल उस मेटाडेटा को चुनते हैं जिसे आप पिछली परिभाषा से रखना चाहते हैं।

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