2012-11-02 13 views
6

जब मेरे पास एक तर्क के लिए प्रासंगिक डेटा है जो इसके तर्क से स्वतंत्र है, तो मुझे स्थानीय encapsulation पर ब्लॉक encapsulation का पक्ष कब करना चाहिए?ब्लॉक encapsulation बनाम स्थानीय encapsulation -

मैं जब उपयोग करना चाहिए:

(let [hello "Hello "] 
    (defn do-greet 
    "Print a greeting." 
    [name] 
    (println (str hello name)))) 

बनाम:

(defn do-greet 
    "Print a greeting." 
    [name] 
    (let [hello "Hello "] 
    (println (str hello name)))) 

उत्तर

6

यदि आप कोड के एक लंबवत स्कॉप्ड ब्लॉक के भीतर स्थिर स्थिरता जैसे मान का उपयोग करना चाहते हैं तो पूर्व एक उचित विकल्प है।

  • मूल्य की गणना करने महंगा है, और आप
  • मूल्य सही मायने में निरंतर, यानी समारोह आमंत्रण
  • भर में परिवर्तन नहीं होगा है यह केवल एक बार जब नाम स्थान भरी हुई है क्या करना चाहते हैं: अगर आम तौर पर आप इस करना होगा
  • मूल्य एकाधिक फ़ंक्शन परिभाषाओं में उपयोग किया जाएगा (यानी आप लेट ब्लॉक के अंदर एकाधिक डिफेंस डालते हैं)
  • (संभवतः?) क्योंकि आप मैक्रो विस्तार के अंदर मूल्य का उपयोग करना चाहते हैं, और मैक्रो विस्तार के अंदर ही एम्बेड करना चाहते हैं अनावश्यक जटिलता जोड़ देंगे।

बाद के संस्करण शायद सबसे अन्य मामलों में प्राथमिकता दी जानी चाहिए, यह अच्छा है कई कारणों से:

  • यह अधिक मुहावरेदार
  • यह समारोह परिभाषा शीर्ष स्तर पर होने की अनुमति देता है, जो कोड पठनीयता/समझ के लिए बेहतर है
  • यह अलग समारोह आमंत्रण
  • यह बेहतर एक स्थानीय संदर्भ
  • में मूल्य का उपयोग करने के इरादे को दर्शाता है पर भिन्न करने की अनुमति देता है मूल्य
+0

मुझे यह पसंद है, आप अधिक अंक कवर करते हैं। मुझे यकीन नहीं है कि आपका मैक्रो विस्तार बिंदु मान्य है क्योंकि आप विस्तार के चारों ओर घूम सकते हैं लेकिन अभी भी फ़ंक्शन के अंदर हो सकते हैं। पठनीयता के लिए, मैं स्टाइलिस्ट विकल्पों को अर्थपूर्ण मतभेदों से अलग करने का सुझाव देता हूं। (मूल्य विभिन्न फ़ंक्शन आमंत्रणों पर भिन्न हो सकता है)। – bmillare

1

निश्चित रूप से इस:

(defn do-greet 
    "Print a greeting." 
    [name] 
    (let [hello "Hello "] 
    (println (str hello name)))) 
2

तो hello केवल कि एक ही समारोह में प्रयोग किया जाता है, इसे और अधिक समझ में आता है फ़ंक्शन के अंदर let डालने के लिए। यदि आप कई कार्यों में hello का उपयोग करने जा रहे थे, तो यह समझ जाएगा कि let उन कार्यों के बाहर और लपेटा गया है।

+0

यदि दोनों रनटाइम के बराबर नहीं हैं, तो मैं तर्क दूंगा कि हमें शैली के आधार पर निर्णय नहीं लेना चाहिए। कल्पना कीजिए कि बाध्यकारी एक स्थिर संसाधन को पढ़ना था '(चलो [हैलो (slurp (clojure.java.io/resource "हैलो"))] ...)। मैंने अपना प्रश्न अधिक सामान्य छोड़ दिया है क्योंकि मुझे नहीं पता कि वे रूप वास्तव में मूल्यांकन कैसे करते हैं और संबंधित ट्रेडऑफ क्या हैं। – ToBeReplaced

+1

कुछ मामलों में शैली के साथ वास्तव में कुछ भी नहीं है। यदि आपको दो अलग-अलग कार्यों में उपलब्ध होने की आवश्यकता है, तो आपको उन कार्यों के दायरे से ऊपर मूल्य उपलब्ध करना होगा। इसके अलावा, @ amalloy का जवाब देखें। – Rayne

5

यह एक स्टाइलिस्ट विकल्प है, और यह संभवतः कम से कम थोड़ा निर्भर करता है कि मूल्य गणना करने के लिए कितना महंगा है। बजाय पर विचार करें:

(defn nth-prime [n] ...) 

(defn f [x] 
    (let [factor (nth-prime 10000)] 
    (* x factor))) 

(let [factor (nth-prime 10000)] 
    (defn g [x] 
    (* x factor))) 

एक महंगी लगातार हर बार f Recomputing कहा जाता है बेकार है, और g एक सरल तकनीक का उपयोग करता यह कर से बचने के लिए।

+3

कहकर रनटाइम व्यवहार (प्रदर्शन) में कोई अंतर है, मैं तर्क दूंगा कि यह एक स्टाइलिस्ट पसंद नहीं है। केवल इसलिए कि पूछताछ के उदाहरण में, व्यावहारिक रूप से कोई अंतर नहीं है, यह स्टाइलिस्ट है। – bmillare

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