是否可以在 Clojure 函数前提条件中使用 Prismatic schema.core/maybe?
Posted
技术标签:
【中文标题】是否可以在 Clojure 函数前提条件中使用 Prismatic schema.core/maybe?【英文标题】:Is it possible to use Prismatic schema.core/maybe in a Clojure function precondition? 【发布时间】:2014-11-19 05:12:56 【问题描述】:我正在尝试在一个带有可选参数opts
的函数的前提条件中使用Prismatic schema.core/maybe
,但是当我调用没有opts
的函数时,它似乎总是抛出一个AssertionError
:
(require '[schema.core :as schema])
(defn foo [& modules]
:pre [(schema/validate (schema/maybe [(schema/enum :foo :bar)]) opts)]
:yay)
(foo :foo)
;=> :yay
(foo :foo :bar)
;=> :yay
(foo)
;=> AssertionError Assert failed: (schema/validate (schema/maybe [(schema/enum :foo :bar)]) modules) user/foo (form-init3808809389777994177.clj:1)
有趣的是,它按预期工作:
(schema/validate (schema/maybe [(schema/enum :foo :bar)]) nil)
;=> nil
我在defn
上使用过macroexpand
,但那里没有任何异常。
我当然可以使用像
这样的先决条件来解决这个问题【问题讨论】:
【参考方案1】:函数前置条件必须评估为真才能通过断言,但schema/validate
如果验证通过则返回正在测试的表达式,如果失败则抛出异常。如果验证通过,您需要更改前提条件以始终返回 true:
(defn foo [& opts]
:pre [(or (schema/validate (schema/maybe [(schema/enum :foo :bar)]) opts) true)]
:yay)
(foo :foo) ;=> :yay
(foo :foo :bar) ;=> :yay
(foo) ;=> :yay
(foo :baz) ;=> ExceptionInfo Value does not match schema: [(not (#:foo :bar :baz))]
【讨论】:
我不敢相信我错过了!我希望 schema 有一个valid?
函数来处理这种情况。我想我可以用(comp nil? schema.core/check)
自己动手。
虽然仔细想想,如果我这样做了,我会丢失 Schema 的漂亮错误消息,所以也许我最好还是坚持(or (nil? ...))
方法。
s/check
是valid?
的否定,而且更有用——它返回描述性错误,如果验证通过则返回 nil。所以更好的前提条件可能是(not (s/check ...))
。以上是关于是否可以在 Clojure 函数前提条件中使用 Prismatic schema.core/maybe?的主要内容,如果未能解决你的问题,请参考以下文章