2012-10-02 19 views
9

मैं in the API docs पढ़ रहा हूं कि *file* चर के पास "स्ट्रिंग के रूप में फ़ाइल का मूल्यांकन किया जा रहा है" का मान होना चाहिए। हालांकि, यह सुविधा कुछ मामलों में टूट गई है।* फ़ाइल * वैरिएबल काम नहीं कर रहा है

जब मैं lein exec का उपयोग कर एक फ़ाइल को निष्पादित, चीजें काम की उम्मीद के रूप में:

$ cat test.clj 
(println *file*) 
$ lein exec test.clj 
/path/to/test.clj 

फिर भी जब मैं एक परीक्षण है कि (println *file*) के लिए एक कॉल में शामिल है चलाने के लिए, NO_SOURCE_PATH कि लाइन युक्त फ़ाइल के बजाय छपा है।

मैं इस व्यवहार को क्यों देख रहा हूं, और मैं मूल्यांकन के लिए फ़ाइल के पथ और फ़ाइल नाम का विश्वसनीय रूप से उपयोग कैसे कर सकता हूं?

उत्तर

13

*file* फ़ाइल संकलित जा रहा है के पथ पर सेट है, इसलिए आपके पूरे कार्यक्रम के बाद यह अब *file* का मूल्य (eval का कोई उपयोग नहीं कल्पना करते हुए) को देखने के लिए उपयोगी है संकलित किया गया है।

आपके test.clj उदाहरण में, println निष्पादित किया गया है जबकि फ़ाइल अभी भी संकलित की जा रही है। यदि *file* का संदर्भ किसी परीक्षण या फ़ंक्शन में ले जाया गया है, तो इसे *file* के मान के बाद केवल रनटाइम पर ही संदर्भित किया जाएगा।

एक विकल्प एक मैक्रो लिखना है जो *file* के मूल्य को विस्तारित करता है, ताकि परिणाम बाद में उपयोग किया जा सके। उदाहरण के लिए, एक फ़ाइल example.clj हो सकता है:

(defmacro source-file [] 
    *file*) 

(defn foo [x] 
    (println "Foo was defined in" (source-file) "and called with" x)) 
आरईपीएल से

तो या कहीं भी, (foo 42) प्रिंट होगा:

Foo was defined in /home/chouser/example.clj and called with 42 

ध्यान दें कि यह कोई फर्क नहीं पड़ता जो फ़ाइल source-file में परिभाषित किया गया है, केवल जहां इसे विस्तारित किया गया था, वह फ़ाइल है जहां foo परिभाषित किया गया है। यह काम करता है क्योंकि यह तब होता है जब foo संकलित किया गया है कि source-file चलाया गया है, और source-file का वापसी मान जो केवल एक स्ट्रिंग है, को foo के संकलित संस्करण में शामिल किया गया है। तब स्ट्रिंग निश्चित रूप से हर बार foo निष्पादित होती है।

यदि यह व्यवहार आश्चर्यजनक है, तो यह विचार करने में मदद कर सकता है कि *file* के लिए रनटाइम पर प्रत्येक फ़ंक्शन के अंदर उपयोगी मूल्य होने के लिए क्या होगा। इसके मूल्य को प्रत्येक फंक्शन कॉल और रिटर्न के लिए बदलना होगा, एक दुर्लभ रूप से उपयोग की जाने वाली सुविधा के लिए एक पर्याप्त रनटाइम ओवरहेड।

+0

ग्रेट स्पष्टीकरण; बहुत बहुत धन्यवाद! –

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