使用 Clojurescript 的宏和 defprotocol
Macros and defprotocol with Clojurescript
我正在将 petrol 用于 clojurescript 应用程序,我发现在使用消息扩展协议时需要大量样板文件。
所以我决定写一个宏!现在,如果它有效的话:/
(ns my.macros)
(defmacro state-message [msg-type app-key]
`(extend-protocol
Message
~msg-type
(process-message [msg app]
(let [state (app-key app)]
(->>
(merge state msg)
(assoc app app-key))))))
上面的代码大致是我想写的,但我在正确引用时遇到了一些问题。当我尝试像 (state-message m/ChangeUsername :user)
那样使用它时,它没有按照我的意图去做,而是给了我一个编译器错误 Invalid local name: ohds.macros/msg
Macroexpand 给了我这个,看起来不错:
(clojure.core/extend-protocol
ohds.server/Message
m/ChangeUsername
(ohds.server/process-message [ohds.server.msg ohds.server/app]
(clojure.core/let [ohds.server/state (ohds.server/app-key ohds.server/app)]
(clojure.core/->>
(clojure.core/merge ohds.server/state ohds.server.msg)
(clojure.core/assoc ohds.server/app ohds.server/app-key)))))
我怀疑 msg
有问题,但我不确定如何继续。
您需要使用 gensym
s 在宏中引入新的本地绑定。
以下应该有效:
(defmacro state-message [msg-type app-key]
`(extend-protocol
Message
~msg-type
(~'process-message [msg# app#]
(let [state# (~app-key app#)]
(->>
(merge state# msg#)
(assoc app# ~app-key))))))
我正在将 petrol 用于 clojurescript 应用程序,我发现在使用消息扩展协议时需要大量样板文件。
所以我决定写一个宏!现在,如果它有效的话:/
(ns my.macros)
(defmacro state-message [msg-type app-key]
`(extend-protocol
Message
~msg-type
(process-message [msg app]
(let [state (app-key app)]
(->>
(merge state msg)
(assoc app app-key))))))
上面的代码大致是我想写的,但我在正确引用时遇到了一些问题。当我尝试像 (state-message m/ChangeUsername :user)
Invalid local name: ohds.macros/msg
Macroexpand 给了我这个,看起来不错:
(clojure.core/extend-protocol
ohds.server/Message
m/ChangeUsername
(ohds.server/process-message [ohds.server.msg ohds.server/app]
(clojure.core/let [ohds.server/state (ohds.server/app-key ohds.server/app)]
(clojure.core/->>
(clojure.core/merge ohds.server/state ohds.server.msg)
(clojure.core/assoc ohds.server/app ohds.server/app-key)))))
我怀疑 msg
有问题,但我不确定如何继续。
您需要使用 gensym
s 在宏中引入新的本地绑定。
以下应该有效:
(defmacro state-message [msg-type app-key]
`(extend-protocol
Message
~msg-type
(~'process-message [msg# app#]
(let [state# (~app-key app#)]
(->>
(merge state# msg#)
(assoc app# ~app-key))))))