में नेस्टेड मैक्रो के बीच संकलन समय राज्य मैं, ऐसा मैक्रो दोनों एक वैश्विक और नेस्टेड तरह से इस्तेमाल किया जा सकता है लिखने के लिए कोशिश कर रहा हूँ तो जैसे:पासिंग Clojure
;;; global:
(do-stuff 1)
;;; nested, within a "with-context" block:
(with-context {:foo :bar}
(do-stuff 2)
(do-stuff 3))
जब नेस्टेड तरह से इस्तेमाल किया, do-stuff
with-context
द्वारा {:foo :bar}
तक पहुंच होना चाहिए।
मैं इस तरह इसे लागू कर लिया है:
(def ^:dynamic *ctx* nil)
(defmacro with-context [ctx & body]
`(binding [*ctx* ~ctx]
(do [email protected])))
(defmacro do-stuff [v]
`(if *ctx*
(println "within context" *ctx* ":" ~v)
(println "no context:" ~v)))
हालांकि, मैं संकलन-समय पर क्रम से do-stuff
भीतर if
शिफ्ट करने के लिए कोशिश कर रहा है, क्योंकि है कि क्या do-stuff
के भीतर से बुलाया जा रहा है with-context
का शरीर या वैश्विक रूप से एक ऐसी जानकारी है जो संकलन-समय पर पहले से ही उपलब्ध है।
दुर्भाग्य से, मैं, एक समाधान खोजने के लिए सक्षम नहीं किया गया है, क्योंकि नेस्टेड मैक्रो एकाधिक "मैक्रो विस्तार रन" में विस्तार करने के लिए लग रहे हैं तो गतिशील (with-context
के भीतर निर्धारित रूप में) *ctx*
के बंधन अब जब उपलब्ध नहीं है do-stuff
विस्तारित हो जाता है। तो यह काम नहीं करता है:
(def ^:dynamic *ctx* nil)
(defmacro with-context [ctx & body]
(binding [*ctx* ctx]
`(do [email protected])))
(defmacro do-stuff [v]
(if *ctx*
`(println "within context" ~*ctx* ":" ~v)
`(println "no context:" ~v)))
कोई विचार यह कैसे पूरा किया जाए?
या मेरा दृष्टिकोण पूरी तरह से पागल है और एक मैक्रो से घोंसले तक इस तरह से राज्य को कैसे पारित करने के लिए एक पैटर्न है?
संपादित:
with-context
के शरीर न केवल do-stuff
(या अन्य संदर्भ जागरूक कार्य/मैक्रो) के साथ, मनमाना भाव के साथ काम करने में सक्षम होना चाहिए। तो कुछ इस तरह भी संभव हो जाना चाहिए:
(with-context {:foo :bar}
(do-stuff 2)
(some-arbitrary-function)
(do-stuff 3))
(मुझे पता है some-arbitrary-function
दुष्प्रभावों के बारे में है कि कर रहा हूँ, यह उदाहरण के लिए एक डेटाबेस के लिए कुछ लिख सकता है।)
बहुत बढ़िया, यह वही है जो मैं खोज रहा था, धन्यवाद! मजेदार तथ्य: मैंने वास्तव में 'मैक्रोएक्सपैंड' और' मैक्रोएक्सपैंड -1 'के साथ यह कोशिश की है लेकिन यह काम नहीं कर सका। मैं बस 'macroexpand-all' के बारे में पता नहीं था। बहुत बहुत धन्यवाद। हालांकि, मैं सोच रहा हूं कि मैक्रोज़ के बीच इस तरह के राज्य को पारित करने का मेरा विचार अवधारणात्मक रूप से उचित है। कोड के भीतर से 'मैक्रोएक्सपैंड' जैसी कुछ कॉल करना हमेशा अजीब लगता है। क्या मुझे यहां एक मुहावरे याद आ रही है जो मेरी समस्या को बेहतर (अधिक मूर्खतापूर्ण, क्लीनर) तरीके से हल करेगी? – Oliver
मुझे इसके बारे में कोई आपत्ति नहीं है: आखिरकार, फ़ंक्शन उपलब्ध कराया गया है ताकि आप इसका उपयोग कर सकें। यह थोड़ा असामान्य है, इसलिए आपको 'संदर्भ के साथ', '* ctx *' के साथ-साथ किसी भी मैक्रो पर एक अच्छा प्रलेखन प्रदान करना होगा जो उस पर निर्भर करता है। यह युग्मन का एक रूप है, लेकिन यदि आपको इसकी आवश्यकता है, तो यह काम करता है। मैं उससे कुछ भी "क्लीनर" के बारे में नहीं जानता। – coredump