這聽起來像一個設計監督與語法引用(在我看來),雖然不清楚一般的「修復」是什麼樣子。
這裏是一個更小例子:
yummly.mobile-api.main> (in-ns 'foo)
#namespace[foo]
foo> (clojure.core/refer-clojure)
foo> (require '[org.httpkit.client :as client])
nil
foo> (defmacro xxz [& fns]
`([email protected]))
#'foo/xxz
foo> (macroexpand-1 '(xxz client/get))
(client/get)
從一個新的命名空間:
foo> (in-ns 'bar)
#namespace[bar]
bar> (macroexpand-1 '(foo/xxz client/get))
(client/get)
bar> (foo/xxz client/get)
CompilerException java.lang.RuntimeException: No such namespace: client, compiling:(*cider-repl api*:87:6)
語法引號形式(又名`)着眼於表達每一個符號,因爲它是被編譯,如果它沒有找到一個/然後它假定它是爲本地命名空間並追加當前命名空間。它只能在宏定義時出現在實際宏中的符號,而不是(因爲我希望它能夠做到)符號作爲參數傳遞給宏。
如果您在宏中使用完全名稱空間限定符號,那麼如果名稱空間中用戶使用宏的名稱空間已將這些符號映射到任何內容,則無需擔心,因爲它們會拼出符號名稱的完整路徑。如果您不想在宏中使用的符號中輸入完整名稱空間,則可以在ns
表達式中的require語句中使用:refer [get]
,這樣可以節省您輸入名稱並使其成爲正確的命名空間在宏定義評估時展開。
因爲語法報價是生產unhygenic符號,則需要兩個都:需要或:指功能在ns
部分在命名空間的頂部,在那裏這些命名空間傳遞給函數的每一位客戶。
另一種方法是找到一些方法來確保符號在編譯語法引用時可用於宏。在某些情況下,這可能會很棘手。
不知道我明白。如果你在ns「sample」中並且調用了(xxz ...),那麼ns「sample」必須有'(:require [some-ns.client:as client])或類似的名稱。 –