与Clojurescript的宏和defprotocol

时间:2015-12-26 14:04:44

标签: macros clojurescript

我正在使用semi-custom action用于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))))))

上面的代码大概是我想写的,但是我在编辑时遇到了一些麻烦。当我尝试使用Invalid local name: ohds.macros/msg

时,它会给我一个编译器错误(state-message m/ChangeUsername :user),而不是按照我的意图行事。

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存在问题,但我不确定如何继续。

1 个答案:

答案 0 :(得分:1)

您需要使用gensym来在宏中引入新的本地绑定。 以下应该有效:

(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))))))
相关问题