다음 Clojure 매크로가 있습니다.
(defmacro with-model
[ref & body]
`(tx
(let [ds# (when (vector? (first ~body)) (ffirst ~body))
name# (when (vector? (first ~body)) (second (first ~body)))
~ref (model ds# name#)]
(do ~@body))))
그리고 나는 이것을 다음과 같이 사용하려고합니다.
(deftest with-model-test
(with-model sandwich
(let [nodes (-> sandwich .listObjects iterator-seq)]
(is nodes))))
아니면 이거:
(deftest with-model-test
(with-model sandwich [*ds* "named-model"]
(let [nodes (-> sandwich .listObjects iterator-seq)]
(is nodes))))
아이디어의 존재는 그 sandwich
지금을 참조해야합니다 Model
,하지만 난 런타임 예외를 얻을 :
Unable to resolve symbol: sandwich in this context
나는 경우 (println ~ref)
매크로에, 나는 모델 인스턴스를 얻을. (println '~ref)
내가 얻는 다면 sandwich
. 대신 어떻게해야합니까?
매크로를 사용할 때의 매크로 확장 with-model
은 (with-model sandwich (let [node (-> sandwich)]))
다음과 같습니다.
(macroexpand-1 '(with-model sandwich (let [node (-> sandwich)])))
(tx
(let [ds (when (vector? (first ((let [node (-> sandwich)]))))
(ffirst ((let [node (-> sandwich)]))))
name (when (vector? (first ((let [node (-> sandwich)]))))
(second (first ((let [node (-> sandwich)])))))
sandwich (model ds name)]
(let [node (-> sandwich)])))
보시다시피 매크로는 확장 후 두 번째 인수에 대해 알아내는 코드를 생성하기 때문에 정의되기 전에 sandwich
사용됩니다 let
. 이 문제를 해결하는 방법은 확장 전에 매크로가 문제를 파악하도록하는 것입니다. 일반적으로 나는 더 간단한 확장을 위해 이것을 시도한다. 비록 그것이 때때로 더 복잡한 매크로 코드를 암시하지만이 경우에는 어렵지 않다.
(defmacro with-model
[ref & [x & _ :as body]]
`(tx
(let [ds# ~(when (vector? x) (first x))
name# ~(when (vector? x) (second x))
~ref (model ds# name#)]
~@body)))
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다