मैं वर-args के रूप में, एक मैक्रो करने के लिए एक समारोह का वर-आर्ग भेजने के लिए अभी भी चाहते हैं में विस्तार करने के लिए कैसे। count=3; args=abc
एक दृश्य (वर-args) अलग आइटम
(test-fn-calling-macro "a" "b" "c")
के उत्पादन में है: count=1; args=("a" "b" "c")
क्योंकि आर्ग मैक्रो के लिए एक एकल तर्क के रूप में भेजा जाता है
(defmacro test-macro
[& args]
`(println (str "count=" ~(count args) "; args=" [email protected])))
(defn test-fn-calling-macro
[& args]
(test-macro args))
(test-macro "a" "b" "c")
के उत्पादन में जो मैं चाहता है: यहाँ मेरी कोड है। मैं कैसे आदेश 3 तर्क के साथ मैक्रो कॉल करने के लिए मेरे समारोह में इस आर्ग विस्तार कर सकते हैं?
मुझे लगता है मैं सिर्फ एक सरल मुख्य कार्य याद कर रहा हूँ लेकिन मैं इसे ढूँढने में सक्षम नहीं हूँ। धन्यवाद
संपादित 2 - मेरे "असली" कोड, नीचे संपादित करें अनुभाग में दिखाए इस तकनीक का उपयोग करने के लिए एक वैध स्थिति नहीं है।
रूप @Brian से कहा, मैक्रो xml-to-cass
इस तरह एक समारोह के साथ बदला जा सकता है:
(defn xml-to-cass
[zipper table key attr & path]
(doseq [v (apply zf/xml-> zipper path)] (cass/set-attr! table key attr v)))
संपादित करें - निम्न अनुभाग अपने मूल प्रश्न से परे चला जाता है लेकिन किसी भी अंतर्दृष्टि का स्वागत है
कोड ऊपर सिर्फ सबसे सरल मैं मेरी समस्या को इंगित करने के साथ आ सकता है है। मेरा असली कोड क्लोज-कैसंड्रा और ज़िप-फ़िल्टर से संबंधित है। यह ओवर-इंजीनियरिंग भी देख सकता है लेकिन यह सिर्फ एक खिलौना प्रोजेक्ट है और मैं एक ही समय में भाषा सीखने की कोशिश कर रहा हूं।
मैं कुछ एक्सएमएल एक कैसेंड्रा डेटाबेस में पाया mlb.com और डालने मूल्यों पर पाया पार्स करने के लिए चाहता हूँ। यहां मेरा कोड और इसके पीछे सोच है।
चरण 1 - समारोह जो ठीक काम करता है लेकिन कोड दोहराव
(ns stats.importer
(:require
[clojure.xml :as xml]
[clojure.zip :as zip]
[clojure.contrib.zip-filter.xml :as zf]
[cassandra.client :as cass]))
(def root-url "http://gd2.mlb.com/components/game/mlb/year_2010/month_05/day_01/")
(def games-table (cass/mk-cf-spec "localhost" 9160 "mlb-stats" "games"))
(defn import-game-xml-1
"Import the content of xml into cassandra"
[game-dir]
(let [url (str root-url game-dir "game.xml")
zipper (zip/xml-zip (xml/parse url))
game-id (.substring game-dir 4 (- (.length game-dir) 1))]
(doseq [v (zf/xml-> zipper (zf/attr :type))] (cass/set-attr! games-table game-id :type v))
(doseq [v (zf/xml-> zipper (zf/attr :local_game_time))] (cass/set-attr! games-table game-id :local_game_time v))
(doseq [v (zf/xml-> zipper :team [(zf/attr= :type "home")] (zf/attr :name_full))] (cass/set-attr! games-table game-id :home_team v))))
शामिल import-game-xml-1
पैरामीटर उदाहरण "gid_2010_05_01_colmlb_sfnmlb_1/"
के लिए हो सकता है। मैं अपने डेटाबेस में कॉलमफैमिली गेम्स की कुंजी बनाने के लिए "gid_" और पिछला स्लैश हटा देता हूं।
मैंने पाया कि 3 doseq
दोहराव का एक बहुत थे (और वहाँ अंतिम संस्करण में अधिक से अधिक 3 होना चाहिए)। तो मैक्रो का उपयोग कोड templating यहाँ उचित लग रहा था (मुझे ठीक कर लें मैं गलत हूँ)।
चरण 2 - कोड templating के लिए एक मैक्रो का परिचय (अभी भी काम करता है)
(defmacro xml-to-cass
[zipper table key attr & path]
`(doseq [v# (zf/xml-> ~zipper [email protected])] (cass/set-attr! ~table ~key ~attr v#)))
(defn import-game-xml-2
"Import the content of xml into cassandra"
[game-dir]
(let [url (str root-url game-dir "game.xml")
zipper (zip/xml-zip (xml/parse url))
game-id (.substring game-dir 4 (- (.length game-dir) 1))]
(xml-to-cass zipper games-table game-id :type (zf/attr :type))
(xml-to-cass zipper games-table game-id :local_game_time (zf/attr :local_game_time))
(xml-to-cass zipper games-table game-id :home_team :team [(zf/attr= :type "home")] (zf/attr :name_full))))
मुझे विश्वास है कि एक सुधार है, लेकिन मैं अभी भी हमेशा xml-to-cass
मेरे कॉल में एक ही 3 मानकों पुन: उपयोग में कुछ दोहराव देखते हैं। यही कारण है कि मैंने उन लोगों की देखभाल करने के लिए एक मध्यवर्ती कार्य शुरू किया था।
चरण 3 - मैक्रो कॉल करने के लिए एक समारोह जोड़ा जा रहा है (यहां समस्या है)
(defn import-game-xml-3
"Import the content of xml into cassandra"
[game-dir]
(let [url (str root-url game-dir "game.xml")
zipper (zip/xml-zip (xml/parse url))
game-id (.substring game-dir 4 (- (.length game-dir) 1))
save-game-attr (fn[key path] (xml-to-cass zipper games-table game-id key path))]
(save-game-attr :type (zf/attr :type)) ; works well because path has only one element
(save-game-attr :local_game_time (zf/attr :local_game_time))
(save-game-attr :home :team [(zf/attr= :type "home"] (zf/attr :name_full))))) ; FIXME this final line doesn't work
धन्यवाद लिखने के लिए समय निकालने के लिए बहुत कुछ। मैं अब प्रबुद्ध महसूस कर रहा हूँ। मैं निश्चित रूप से भी आपके ब्लॉग पोस्ट के माध्यम से जाना होगा। बहुत बुरा मैंने लिस्प को नहीं सीखा जब मैं एक जिद्दी वयस्क के बजाय एक बच्चा था। मुझे अपने दिमाग को इसके चारों ओर लेना मुश्किल है। लेकिन अब तक यह दर्द के लायक है। मैं हार नहीं मानूंगा और आशा करता हूं कि सोच को समझें। – Damien
काटा में जवाब देने के लिए खेद है! वहाँ subtleties हैं, और समझने से पहले कुछ समय के लिए खेलना है। अपने दिमाग के बारे में चिंता मत करो। जब तक मैं 35 वर्ष का नहीं था तब तक मैंने एक प्रतिलिपि नहीं छूटी। इसमें लगभग एक वर्ष लगते हैं। एक दिन आप सिंटैक्स के साथ एक भाषा में कुछ लिखने की कोशिश करेंगे और अचानक महसूस करेंगे कि आप इससे फंस गए हैं। –
वास्तव में इसे ग्रोक करने का तरीका एसआईसीपी के माध्यम से जाना और सभी अभ्यास करना है। http://mitpress.mit.edu/sicp/ वास्तव में यह शायद ही मैक्रोज़ का उल्लेख करता है, लेकिन उस समय के बारे में जहां आप योजना में एक योजना दुभाषिया लिखते हैं, आप समझेंगे कि मूल्यांकनकर्ता में क्या हो रहा है, और उस बिंदु पर मैक्रोज़ हैं एक मामूली अनुशासनिक। यहां तक कि यदि आपका लक्ष्य क्लोजर या कुछ अन्य जटिल लिस्प में प्रोग्राम करना है, तो यह करना एक अच्छी बात है, क्योंकि योजना इतनी सरल है कि आप विचार देख सकते हैं। जावा सीखने की तरह थोड़ा पहले अगर आप वास्तव में करना चाहते हैं तो सी ++ है। –