2024 Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面以获取更多关于如何操作的信息。

+1
Spec
对由一些嵌套在?

的一些<>{{cat}}}组成的spec调用<>{{conform}}}

然后调用<>{{unform}}}

将导致结果增加一个嵌套级别


(require '[clojure.spec :as s])

(let [spec (s/? (s/cat :foo #{:foo}))
      initial [:foo]
      conformed (s/conform spec initial)
      unformed (s/unform spec conformed)]
  [initial conformed unformed])
;;=> [[:foo] {:foo :foo} [(:foo)]]


只有单独使用{{?}}或{{cat}}时不会出现这种行为


(let [spec (s/? #{:foo})]
  (s/unform spec (s/conform spec [:foo])))
;;=> [:foo]

(let [spec (s/cat :foo #{:foo})]
  (s/unform spec (s/conform spec [:foo])))
;;=> (:foo)


*补丁:* CLJ-2003-corrected.patch

10个答案

0

评论者:pbrown

我遇到了另一个案例,其中重复一个或多个序列,并且在开始或结束时有一个可选元素,其中该元素的谓词也匹配另一端的元素,结果多出了额外的嵌套

user=> (s/conform (s/+ (s/cat :k any? :v (s/? any?))) [:a 1 :b 2]) [{:k :a, :v 1} [{:k :b, :v 2}]]

我期望的是

`[{:k :a, :v 1} {:k :b, :v 2}] `

以下给出期望结果

user=> (s/conform (s/+ (s/cat :k any? :v (s/? any?))) [:a 1 :b]) [{:k :a, :v 1} {:k :b}] user=> (s/conform (s/+ (s/cat :k keyword? :v (s/? int?))) [:a 1 :b 2]) [{:k :a, :v 1} {:k :b, :v 2}] user=> (s/conform (s/* (s/cat :k any? :v (s/? any?))) [:a 1 :b 2]) [{:k :a, :v 1} {:k :b, :v 2}]

0
by

评论者:alexmiller

Phil,我认为你的示例是不同的问题,你应该为此问题创建一个新的jira。

0
by

评论者:alexmiller

好吧,也许我会收回前言,它们可能是相关的。

0
已回答 by

评论者:bbloom

我在尝试理解一些定义表单时遇到了这个问题。这是一个示例:

user=> (s/unform :clojure.core.specs/defn-args (s/conform :clojure.core.specs/defn-args '(f (link: &aamp; xs))))
(f ((&aamp; xs)))

0
by

评论者:[email protected]

这似乎就是所有所需的内容。

0
by
评论者:favila_

这个问题实际上比 {{(? (cat ...))}} 更普遍。当一个 {{s/?}} 有任何正则表达式子操作时,{{s/unform}} 会引入一个额外的嵌套层次。当我们子操作是正则表达式时,我们正在消费同一“级别”的序列,所以 unform 不应该引入额外的层级。然而在其他情况下(非正则表达式操作),我们仍可能产生一个嵌套集合。

之前的补丁过于激进:它解包了 {{s/?}} 的所有子-unform。这个补丁 CLJ-2003-corrected.patch 只在子操作是正则表达式时解包。

遗憾的是,无法区分期望的但可选的 nil 与 {{s/?}} 的不匹配。具体来说,以下测试现在是有效的:


(testing "s/? 匹配空值")
  (is (nil? (s/conform (s/? nil?) [nil])))
  (is (nil? (s/conform (s/? nil?) [])))
  (is (nil? (s/conform (s/? nil?) nil)))
  (is (= (s/unform (s/? nil?) nil) [])))


(我没有将这些测试添加到补丁中,因为我不确定它们是否应该是 unform 合同的一部分。然而,它们是很大的陷阱。)

我还增加了对所有可能的子操作{{s/?}}的测试,除了{{::s/accept}},因为我没有考虑出一个测试用例。 (我不确定{{::s/accept}}是否实际上可以在{{s/op-unform}}内部访问?)
0

评论者:alexmiller

感谢大家为此项目努力工作 - 我有空的时候会看一下。

0

评论者:favila

我不得不稍微修改我的补丁(同一名称):其中一个测试用例没有测试正确的东西。

0

评论者:favila

由于其他提交中添加的测试,补丁不再干净地应用到master上。 将补丁重新应用到master

0
参考:https://clojure.atlassian.net/browse/CLJ-2003 (由 alex+import 报告)
...