2024年Clojure现状调查!分享您的想法。

欢迎!请查看关于页面,了解更多关于如何使用本站点的信息。

0投票
Spec

摘要

1) 给定一个懒加载调用的仪表化函数{{map-f}},例如{{(def ls (map map-f (range)))}}。
2) 还有一个仪表化函数{{varargs-f}},是一个可变参数函数。当将{{LazySeq}}传递给{{varargs-f}}时,一些或全部元素在符合条件的过程中被实现。
3) 问题:当调用{{(apply varargs-f ls)}}时,一些对{{map-f}}的无效调用可能不会被注意到。

重现示例

在以下代码中,{{map-f}}在以非{{Symbol}}调用时应抛出异常。然而,对{{map-f}}的调用(使用{{String}})却成功通过。

`
(ns repro
(:require
[clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as stest]))

(defn map-f [x]
(println "以类型" (type x) "调用my-fn")
(println (deref #'clojure.spec.test.alpha/instrument-enabled))
{x 1})

(s/fdef map-f :args (s/cat :x symbol?))

(defn varargs-f [& maps]
true)

(s/fdef varargs-f :args (s/cat :maps (s/* map?)))

(defn repro [& args]
(apply varargs-f (map map-f args)))

(stest/instrument)

(repro 'foo 'bar "baz")
`

输出

以类型 clojure.lang.Symbol 调用my-fn true 以类型 clojure.lang.Symbol 调用my-fn true 以类型 java.lang.String;; < -- nil

原因

当{{varargs-f}}的参数在符合条件后变为实际情况时,一些对{{map-fn}}的调用在{{with-instrument-disabled}}的作用域内进行:https://github.com/clojure/spec.alpha/blob/f23ea614b3cb658cff0044a027cacdd76831edcf/src/main/clojure/clojure/spec/test/alpha.clj#L140

背景

我在spec'ing {{merge-with}}时遇到了这个问题。某些测试空间中的spec'ed fn不再抛出异常,因为clojure.test中与此类似的问题:https://github.com/clojure/clojure/blob/28efe345d5e995dc152a0286fb0be81443a0d9ac/src/clj/clojure/test.clj#L775

CLJ-2443.patch包含了一个修复,但我意识到它可能还不够完美。因此,我提供了CLJ-2443-test.patch,其中只包含单元测试,可以用来测试替代方案。

4 答案

0投票
by

评论由:borkdude发表

CLJ-2443.patch通过在with-instrument-disabled作用域外对Cons类型参数进行适应性修复这个问题。
提供了测试。此补丁适用于speculative (https://github.com/slipset/speculative)。

0投票
by

评论由:borkdude发表

CLJ-2443-test只包含测试,不包含修复本身。

0投票
by

评论由:borkdude发表

使用CLJ-2443-test.patch更新描述

0投票
by
参考: https://clojure.atlassian.net/browse/CLJ-2443 (由borkdude报告)
...