我写了一个宏
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
答案 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})