我写了一个宏
(defmacro defendpoint [msg-type url-key schema]
`(defrecord ~msg-type []
Create
(create [entity#]
(s/validate ~schema entity#)
(create-entity (~url-key urls) entity#))))
Run Code Online (Sandbox Code Playgroud)
我正在使用它
(defendpoint Location :locations
{... my schema ...}})
(defendpoint LocationHierarchy :location-hierarchies
{... my schema ...}})
Run Code Online (Sandbox Code Playgroud)
我第一次使用宏时,它有效
(create (map->Location
{... data ...}))
=> { ... json response ...}
Run Code Online (Sandbox Code Playgroud)
但是第二次,它失败了:
(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
Run Code Online (Sandbox Code Playgroud)
我不确定为什么会这样。我希望第二个调用的工作方式与第一个相同,但似乎验证步骤中存在错误。事实上,如果我(s/validate...)从宏中删除,它会按预期工作。所以我不确定这里到底发生了什么。
我将介绍我如何解决我的问题,希望该方法可以帮助其他人。
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" %))))
Run Code Online (Sandbox Code Playgroud)
方法
我从错误开始: No implementation of method: :spec of protocol:
#'schema.core/Schema found for class: ohds.client$fn__32303
一开始我不确定这意味着什么。:spec of protocol:把我扔了。但我确实看到它提到了schema.core/Schema,所以我阅读了源代码。我发现 Schema 是一个带有方法的协议spec,就像错误所说:/
下一个令人困惑的部分是for class: ohds.client$fn__32303. 我想知道为什么我的命名空间需要实现协议。那没有任何意义。然后我注意到了$fn_32303。这告诉我在错误所在的地方有一个 lambda!
在这一点上,我的假设是我的模式有问题。所以我从我的模式中删除了所有特殊的验证,并s/Str在任何地方使用它来查看它是否有效。确实如此,所以我来对地方了!我一次添加一个特殊验证,直到测试再次失败。问题出在我的日期模式中。
我查看了我在它上面定义的模式,看看有什么不同。在那里我注意到我未能将我的 lambda 包装在s/pred.
道德
Clojure 设计得很好,因此错误消息会准确地告诉您出了什么问题。你只需要理解它。
| 归档时间: |
|
| 查看次数: |
1522 次 |
| 最近记录: |