2024年Clojure调查问卷中分享你的想法!

欢迎!请参阅关于页面,获取关于如何使用本站的一些更多信息。

0
错误
以下是一个可以粘贴到REPL中的实现。期待反馈


(defn ^{:private true} local-bindings
  "生成一个局部绑定名称与其值的映射表."
  [env]
  
  

    
  "当expr的值不是逻辑真时,会抛出异常。"
  {:added "1.0"}
  [x]
    
    
    
    
    
    
  

15 答案

0

评论作者:importer

fogus表示:嗯,但是这完全失败了:(let(link: x 1 y 2 z 3 a 1 b 2 c 3) (assert (= (link: x y) (link: a c)))),所以最好是打印所有局部变量,除非你真的需要复杂化。
:f

0

评论作者:importer

http://www.assembla.com/spaces/clojure/tickets/415 转换而来

0

评论作者:importer

alexdmiller 说:为了说明,我尝试了一个简单的例子

`user=> (let [a 1 b 2] (assert (= a b)))

<编译器异常 java.lang.AssertionError:断言失败: (= a b)>

a : 1
b : 2
`

0

评论作者:importer

jawolfe 说:还可以参考以下一些评论

http://groups.google.com/group/clojure-dev/browse_frm/thread/68d49cd7eb4a4899/9afc6be4d3f8ae27?lnk=gst&q=assert#9afc6be4d3f8ae27

另外,我还有一个建议可以加入讨论:除了/而不是打印局部变量,将其保存到某个地方怎么样。例如,变量 assert-bindings 可以绑定到局部变量的映射上。这样,你不会遇到无限/非常大的序列问题,并允许用户对错误值进行更详细的调查(特别是在一些变量打印得不清楚时特别有用)。

0

评论作者:importer

stuart.sierra 说:还有一个我乐意贡献的方法
http://github.com/stuartsierra/lazytest/blob/master/src/main/clojure/lazytest/expect.clj

0
_注释由:导入器_添加

fogus 说:如果你做了像这样做的话,那就很奇怪:
(let [x 1 y 2 z 3 a 1 b 2 c 3] (assert (= x y)))
java.lang.AssertionError:断言失败: (= x y)
 x : 1
 y : 2
 z : 3
 a : 1
 b : 2
 c : 3
 (无文件来源: 0)
</code></pre>

所以,可能需要进行一些改进:
<pre><code>(defmacro assert
  "评估 expr,如果它不评估为逻辑真则抛出异常。"
  [x]
    
    
    
    
         (let [sep#  (System/getProperty "line.separator")
               form# '~x]
           (throw (AssertionError. (apply str "断言失败: " (pr-str form#) sep#
                                            (~bindings))))])))))
 (defmacro assert)
  "评估 expr,如果它不评估为逻辑真则抛出异常。"
         (let [sep#  (System/getProperty "line.separator")
</code></pre>

               form# '~x]
<pre><code>(let [x 1 y 2 z 3 a 1 b 2 c 3] (assert (= x y)))
java.lang.AssertionError:断言失败: (= x y)
 x : 1
 y : 2
 (无文件来源: 0)

:f
0
评论由:jweiss_添加

我对fogus的最后一则评论进行了一处细微调整,这也是我正在使用的。在你可以使用'some'检查局部变量是否以该形式使用之前,你需要对引用的表单进行展开。

    
  "评估 expr,如果它不评估为逻辑真则抛出异常。"
  [x]
    
    
    
    
         (let [sep#  (System/getProperty "line.separator")
               form# '~x]
           (throw (AssertionError. (apply str "断言失败: " (pr-str form#) sep#
                                            (~bindings))))])))))
    (当(some #{k#} (flatten form#))时)
  "评估 expr,如果它不评估为逻辑真则抛出异常。"
         (let [sep#  (System/getProperty "line.separator")
0
0
评论由:stu添加

当你可以指定回调(见下文)时,为何要猜测某人想要对局部变量(或其他任何上下文)做什么呢?上周当我在CI盒子上有一个失败的断言时,这很有用,因为那里的调试器不可用。

Rich,我有话要说,我仍然认为这是一个好主意。调试器并不总是可用,这是一个Lisp天生就能提供比其他环境更好的信息的例子。如果你想对以下代码进行修补,请标记等待我的回复,否则请拒绝此工单,这样我就不会再看了。:-)



(def ^:dynamic *assert-handler* nil)

(defn ^{:private true} local-bindings
  "生成一个局部绑定名称与其值的映射表."
  [env]
  
  

    
    
    
    
    
         (let [sep#  (System/getProperty "line.separator")
               form# '~x]
           (if *assert-handler*
             (*assert-handler* form# ~bindings)
             (throw (AssertionError. (apply str "断言失败: " (pr-str form#) sep#
                                             (map (fn [[k# v#]]
                                                   (when (some #{k#} (flatten form#))
                                                     (str "\t" k# " : " v# sep#)))
                                                 ~bindings))))))))))
0

评论者:jweiss

我在自己的代码版本中做出的微小改进:flatten函数不影响集合字面量。所以如果你这样做(assert (some #{x} (link: a b c d))),x的值将不会被打印。下面是修改后的flatten函数

(defn symbols [sexp] "从表达式中返回所有符号,包括那些在字面量(集合、映射、列表、向量)内部的符号。" (distinct (filter symbol? (tree-seq coll? seq sexp)))))

0

评论者:jafingerhut

附上Stuart Halloway这个想法的版本:git格式补丁clj-415-assert-prints-locals-v1.txt。我并不是在推广它,只是将文件附加到JIRA问题跟踪上。

0

评论者:michaelblume

之前的补丁与CLJ-1005不兼容,CLJ-1005将zipmap移动到clojure.core中较晚的位置。我已经重新编写以使用into。

0

评论者:michaelblume

两个补丁似乎都与CLJ-1224不兼容。在我构建自己的compojure-api项目时,我得到了以下错误

`
主线程中的一个异常:java.lang.UnsupportedOperationException: 不能为原始局部变量类型提示,编译:(schema/core.clj:680:27)

at clojure.lang.Compiler.analyze(Compiler.java:6569)
       ...
at clojure.main.main(main.java:37)

原因:java.lang.UnsupportedOperationException: 不能为原始局部变量类型提示

at clojure.lang.Compiler$LocalBindingExpr.<init>(Compiler.java:5792)
at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6929)
at clojure.lang.Compiler.analyze(Compiler.java:6532)
... 299 more

失败。
`

0

评论者:jafingerhut

Michael,你找到这些补丁之间的不兼容性是因为你想运行带有所有这些补丁的修改版Clojure吗?如果这样的话,我明白了。

如果你在寻找彼此不兼容的补丁对,我建议找个不同的爱好吧。每月平均大约有9个补丁需要应用,所以应该有足够的时间在之后解决它们之间的一致性问题。

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