2015-08-29 6 views
6

uberjar बनाते समय मैं "लिएनिंगेन" व्यवहार को समझने की कोशिश कर रहा हूं।`lein uberjar`` def` के साथ परिभाषित चर का मूल्यांकन क्यों करता है?

(ns my-stuff.core 
    (:gen-class)) 

(def some-var (throw (Exception. "boom!"))) 

(defn -main [& args] 
    (println some-var)) 

जब यह lein run साथ क्रियान्वित किया जाता है यह स्पष्ट रूप से एक अपवाद के साथ विफल: के बाद कम से कम उदाहरण जो व्यवहार पुनरुत्पादित करता है। हालांकि, मुझे समझ में नहीं आ रहा है कि lein uberjar निष्पादित क्यों चर परिभाषा से अपवाद के साथ विफल रहता है? lein uberjar निष्पादित करने का प्रयास वैरिएबल मान का मूल्यांकन करने का प्रयास क्यों करता है? क्या यह uberjar कार्य के लिए विशिष्ट है या क्या मुझे क्लोजर या लीइंगेन के बारे में कुछ और याद आ रही है?

उत्तर

10

uberjar के लिए अपना नामस्थान संकलित करने के लिए (यदि आपके पास एओटी चालू है), क्लोजर कंपाइलर को अपना नामस्थान लोड करना होगा। यह हमेशा सभी शीर्ष-स्तरीय दुष्प्रभावों का आह्वान करेगा।

इसे संभालने का सबसे अच्छा तरीका शीर्ष स्तर कोड (चाहे def रूप के अंदर या बाहर) में साइड इफेक्ट्स न हो, और प्रारंभिक कार्यों को किसी भी स्टार्ट-अप साइड इफेक्ट्स को महसूस करने के लिए प्रारंभिक कार्य हो।

का संभावित हल एक छोटा सा नाम स्थान आत्मनिरीक्षण का उपयोग करता है रनटाइम पर नहीं बल्कि अपने कोड के बाकी लोड करने के लिए, जबकि संकलन करने के लिए हो सकता है - इस तरह एक समारोह का उपयोग कर:

(defn -main 
    [] 
    (require 'my.primary.ns) 
    ((resolve 'my.primary.ns/start))) 

अगर उस नाम स्थान संकलित किया गया है, आपके अन्य कोड को संकलित किए जाने के बावजूद, जेवीएम मिल सकता है और इसे चला सकता है। रनटाइम require क्लोजर कंपाइलर को आपके शेष कोड को केवल रनटाइम पर लोड करने का कारण बनता है, और resolve आवश्यक है ताकि -main साफ़ रूप से संकलित हो जाए - यह विभिन्न संदर्भ देता है, जो तब आपके फ़ंक्शन को बुलाता है।

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