符号与宏中的错误命名空间相关联

时间:2016-02-11 01:27:49

标签: clojure macros clojurescript

我有这个宏:

(defmacro widget [msg-type value & app-key]
  `(defrecord ~msg-type [~value]
     Message
     (~'process-message [msg# app#]
      (let [state# (~@app-key app#)]
        (dissoc
         (->>
          (merge state# msg#)
          (assoc app# ~@app-key))
         :errors)))))

Messagea clojurescript dependency中定义的协议,具有process-message功能。

当我尝试使用widget时,

(ns my.cljs.ns
  (:require-macros [my.ns.macros :as macro])
  (:require [petrol.core :refer [Message]]))

(macro/widget A-Record a-field :a-key)

我收到此错误:

Bad method signature in protocol implementation, 
my.ns.macros/Message does not declare method called 
process-message ...

如何让消息引用petrol/Message而不是my.ns.macros/Message

1 个答案:

答案 0 :(得分:2)

你需要神秘的力量〜'运营商:) 我看到你已经调用了它来处理进程消息,所以也许你已经熟悉了为什么;但是为了答案的目的,反引号中的内容获得完全命名空间限定,其中评估引用将文字符号放在适当的位置。

public class test {
    public int sumOfDigits(String s) {
        int sum = 0;
        for (int i=0; i<s.length(); i++) {
            char cur = s.charAt(i);

            if (cur >= 0 && cur <= 9) {
                sum += cur - '0';
            }
        }

        return sum;
    }
}

如果您想避免将当前ns附加到其上,则错误消息表明您需要(macroexpand-1 '(widget :a :b))

然而,具有汽油命名空间的完全符合条件的消息将是一个很好的举动IMO

~'Message

这样你就不需要依赖ns声明中的引用了。请注意,您不需要〜&#39;它要么。

另外我会警惕(〜@ app-key app#),因为app-key是可选的...你可以得到任何东西,它会调用#app是什么,这听起来不像是什么东西你想要发生。同样地传递不止一个似乎很奇怪。也许它应该是必需的参数?