try
在一個宏中,catch
在第二個由第一個調用的宏中。如何讓以下工作?可以嘗試捕捉不同的(但是嵌套的)宏嗎?
(defmacro catch-me []
`(catch ~'Exception ~'ex
true))
(defmacro try-me []
`(try (+ 4 3)
(catch-me)))
擴大try-me
看起來不錯:
(clojure.walk/macroexpand-all '(try-me))
產生
(try (clojure.core/+ 4 3) (catch Exception ex true))
但調用(試行-ME)產量:
"Unable to resolve symbol: catch in this context",
其中,順便說一句,也是你會在REPL中獲得的消息在不嘗試的時候使用catch。
UPDATE:
這是我如何能得到它的工作(感謝,@Barmar),在這裏你可以看到我的代碼的實際背景:
(defmacro try-me [& body]
`(try
[email protected]
[email protected](for [[e msg] [[com.mongodb.MongoException$Network "Database unreachable."]
[com.mongodb.MongoException "Database problem."]
[Exception "Unknown error."]]]
`(catch ~e ~'ex
(common/site-layout
[:div {:id "errormessage"}
[:p ~msg]
[:p "Error is: " ~e]
[:p "Message is " ~'ex]])))))
,但是這是我希望(使用單獨的宏catch-me
):
(defmacro try-me [& body]
`(try
[email protected]
(catch-me com.mongodb.MongoException$Network "Database unreachable.")
(catch-me com.mongodb.MongoException "Database problem.")
(catch-me Exception "Unknown error.")))
我認爲這將是更容易編寫/維護。
任何想法?我需要語法引用,因爲我傳遞參數,這就是爲什麼不幸的是,Arthur的答案不能被應用(或者它可以以某種方式?),但是直到現在我才發佈我的實際上下文。
我目前的猜測是,(你追我趕)首先擴大,然後很明顯,它是在一個嘗試。是嗎?如何戰鬥呢? – 0dB
只有在正常評估表達式的地方纔會擴展宏。 'catch'子表單不是被評估的表達式,它們是'try'語法的一部分。 – Barmar
我目前仍然認爲這個問題沒有答案。令人困惑的是,爲什麼Arthur的例子能夠工作,但是使用語法引用的卻沒有,而且,這個macroexpand-all顯示了一個正在運行的宏擴展,但直接調用它卻失敗並報錯。感謝Barmar提供的解決方法。任何其他想法,任何人? – 0dB