2011-09-16 8 views
5

किसी विशेष नामस्थान पर मैं काम कर रहा हूं, मैं फ़ंक्शन नामों से बाहर निकलना शुरू कर रहा हूं। अगर मैं एक ऐसे नाम का पुन: उपयोग करता हूं जो पहले से ही उसी नामस्थान में किसी फ़ंक्शन से जुड़ा हुआ है, तो मुझे एक अन्य नामस्थान से एक प्रतीक ओवरराइड करने की तरह चेतावनी प्राप्त करने का कोई तरीका है?ओवरराइडिंग वेरिएबल नामों से बचें

+0

आप इसे उस भाषा/env के साथ टैग करना चाहते हैं जिसमें आप विकास कर रहे हैं या इसे विवरण में जोड़ सकते हैं। एनएम आपने अभी किया – Zak

+0

क्या घटना होती है जो आपको बताती है कि आप फ़ंक्शन नाम से बाहर हैं? मैं पिछले मई से क्लोजर सीख रहा हूं, इसलिए मैंने कभी ऐसा नहीं होने के बारे में सुना है। – octopusgrabbus

+0

क्या कुछ नामस्थान को एक या अधिक अन्य नामस्थानों में विभाजित किया जाना चाहिए? – compman

उत्तर

4

तो यह एक समस्या के लिए पर्याप्त है कि आप एक कोर मैक्रो (रों) (का सेट) को बदलने के लिए तैयार हो जाएगा है, तो आप इस दृष्टिकोण की कोशिश कर सकते defn साथ वार असफल हो जायेगी:

user=> (defn foo [] :foo) 
#'user/foo 
user=> (defn foo [] :bar) 
AssertionError Assert failed: Attempting to redefine already defined Var #'user/foo 
(nil? (resolve name)) user/defn (NO_SOURCE_FILE:2) 

आप इसी तरह defmacro की जगह सकता है; उस स्थिति में आपको अपने स्वयं के संस्करण को परिभाषित करते समय clojure.core/defmacro पर कॉल करना होगा।

सादा, unadorned def एक विशेष रूप है और संकलक से जादू उपचार प्राप्त करता है, ताकि आप इसके साथ मौजूदा वर्रों को ओवरराइट कर सकें। यदि आप उस झुकाव पर भी नाम झड़पों से बचना चाहते हैं, तो आप एक समान कस्टम जोर के साथ defvar (clojure.contrib.def में उपलब्ध होने के लिए उपयोग किए गए) पर स्विच कर सकते हैं।

+0

बस स्पष्ट करने के लिए, 'def' नामक मैक्रो को पंजीकृत करना संभव है, लेकिन संकलक इसे अनदेखा कर देगा। साथ ही, यदि "नाम से बाहर चलना" समस्या केवल एक नामस्थान तक ही सीमित है, तो मै मैक्रोज़ को इसके ऊपर रखूंगा; अन्यथा उन्हें अपने नामस्थान में रखना और जहां भी आवश्यक हो, इसका उपयोग करना अधिक सुविधाजनक होगा। सभी क्लाइंट नेमस्पेस को अभी भी 'रेफर-क्लोजर' क्लॉज का उपयोग करने की आवश्यकता होगी। –

2

यह आपके प्रश्न का उत्तर नहीं है लेकिन इस मुद्दे से बचने में आपकी मदद कर सकता है कि आपके नामस्थान में फ़ंक्शंस का उपयोग कैसे किया जा रहा है। आप letfn का उपयोग करके स्थानीय कार्यों में उन्हें बना सकते हैं, जिससे आप उन फ़ंक्शंस के नामों का पुन: उपयोग कर सकते हैं जिनका उपयोग केवल किसी अन्य फ़ंक्शन के संदर्भ में किया जाता है।

(defn main-fn [x] 
    (letfn [(secondary-fn [x] (* x x)) 
      (another-fn [x] (secondary-fn (inc x)))] 
    (/ (another-fn x) 4))) 
1

यहां तक ​​कि अगर आप अपने आप को एकल चरित्र फ़ंक्शन नाम तक सीमित है, तो आप बाहर चलाने का कोई खतरे में हैं, के रूप में वहाँ (के बारे में) 64 हजार यूनिकोड वर्ण हैं, जिनमें से किसी भी एक के लिए एक वैध समारोह का नाम है।

यह देखते हुए कि आप वास्तव में ऐसे नाम हैं जो दस हजार वर्ण लंबे हैं, आप भी सुरक्षित जमीन पर हैं।

(ns huge.core 
    (:refer-clojure :exclude [defn])) 

(defmacro defn [name & defn-tail] 
    (assert (nil? (resolve name)) 
      (str "Attempting to redefine already defined Var " 
       "#'" (.name *ns*) "/" name)) 
    `(clojure.core/defn ~name [email protected])) 

फिर एक मौजूदा फिर से परिभाषित करने का कोई भी प्रयास:

+0

प्रत्येक वैध प्रतीक नहीं है (चाहे क्लोजर मनमाने ढंग से यूनिकोड वर्णों के साथ एक प्रतीक पढ़ने का समर्थन करता है) एक उपयोगी पहचानकर्ता है। उदाहरण के लिए aolskSAdjfjlDFksdioeFwmvkldjskSFODIJFLKSMEOVISLEKasdeDFeasD एक पूरी तरह से वैध प्रतीक होना चाहिए, लेकिन आपको वास्तव में अंग्रेजी नामों के साथ एक वास्तविक कार्यक्रम में पहचानकर्ता के रूप में इसका उपयोग नहीं करना चाहिए। – compman

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