没有实现方法:: protocol of protocol:#'schema.core / Schema

时间:2016-02-14 23:07:42

标签: clojure

我写了一个宏

x

我正在使用它

(defmacro defendpoint [msg-type url-key schema]
  `(defrecord ~msg-type []
     Create
     (create [entity#]
       (s/validate ~schema entity#)
       (create-entity (~url-key urls) entity#))))

我第一次使用宏时,它可以正常工作

(defendpoint Location :locations
  {... my schema ...}})

(defendpoint LocationHierarchy :location-hierarchies
  {... my schema ...}})

但第二次失败了:

(create  (map->Location
          {... data ...}))

=> { ... json response ...}

我不确定为什么会这样。我希望第二个调用的工作方式与第一个相同,但似乎验证步骤中存在错误。实际上,如果我从宏中删除(create (map->LocationHierarchy {... data ...})) => 1. Unhandled java.lang.IllegalArgumentException No implementation of method: :spec of protocol: #'schema.core/Schema found for class: ohds.client$fn__32303 ,它会按预期工作。所以我不确定这里到底发生了什么。

I've created a gist that shows the entire file I'm working with

2 个答案:

答案 0 :(得分:3)

我将通过如何解决我的问题,希望该方法可以帮助其他人。

<强> TL;博士

;; Wrong:
(def date-schema (s/both s/Str #(re-matches #"my-regex" %)))
;; Right:
(def date-schema (s/both s/Str (s/pred #(re-matches #"my-regex" %))))

方法

我从错误开始:No implementation of method: :spec of protocol: #'schema.core/Schema found for class: ohds.client$fn__32303

我一开始并不确定这意味着什么。 :spec of protocol:让我失望。但我确实看到它提到schema.core/Schema,所以我读了the source code。我发现Schema是一个方法spec的协议,就像错误说:/

一样

令人困惑的下一部分是for class: ohds.client$fn__32303。我想知道为什么我的命名空间需要实现协议。这没有任何意义。然后我注意到$fn_32303。这告诉我在错误发生的地方有一个lambda!

此时,我的假设是我的架构出了问题。所以我从我的架构中删除了所有特殊验证,并在任何地方使用s/Str来查看它是否有效。它确实如此,所以我在正确的位置!我一次又一次添加了特殊验证,直到测试再次失败。问题出在我的日期架构中。

我查看了我在其上方定义的模式,看看有什么不同。在那里,我注意到我没有把我的lambda包裹在s/pred

道德

Clojure设计得很好,所以错误信息告诉你到底出了什么问题。你只需要了解它。

答案 1 :(得分:0)

这只是发生在我身上。原来我有一个defschema在引用自己:

(s/defschema Templates {:templates [Templates]
                        :error     s/Bool})

代替正确的参考:

(s/defschema Templates {:templates [Template]
                        :error     s/Bool})