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

欢迎!请参阅 关于 页面以了解更多此网站的工作方式。

0
规范

目前,{{instrument}} 和 {{unstrument}} 对于测试和开发中的无条件仪器化非常出色。我还想对代码的特定部分运行仪器。例如,我想使用某些存根或覆盖。目前,我需要仪器化和去仪器化;我更希望有一个 with-instrument 宏为我自动完成显式的 try/finally 块。

3 个答案

0

评论者:alexmiller

所以(和大多数事情一样),明显的事情并不明显。 :)

有多种方式调用仪器

  • (instrument)
  • (instrument sym)
  • (instrument (link: syms))
  • (instrument sym opts)
  • (instrument (link: syms) opts)

这里的数字是可变的。类似地,其他 with-style 宏中的“主体”通常也是可变参数。解析这两个可变参数是模糊的。

你提到了 opts 映射,所以我假设你想要它作为可选参数。因此,您可以缩小参数为:(link:sym-or-syms opts & body)。不确定你是否因此引入了一些在常见情况下不需要的东西,从而破坏了宏的有用性。

(with-instrument `my-fun {my-opts ...} (test-something))

将扩展为

`
(do
(instrument user/my-fun {my-opts ...})
(try

(test-something)
(finally
  (unstrument user/my-fun))))

`

也许我们可以思考一下有多少已经仪器化的要考虑。你是取消你已经仪器化的吗,或者尝试将仪器化恢复到原来的状态(其中一些东西可能已经被仪器化)?

0

评论者:dsg

因此,这是我一直在使用的实现,这不一定是要使用的实现,但我认为它有助于解决一些关于参数的模糊性。

`
定义宏 with-instrumentation
参数 [args & body]
`(let [[arg1# arg2#] ~args

     [sym-or-syms# opts#] (cond
                            (nil? arg1#) [(stest/instrumentable-syms) arg2#]
                            (map? arg1#) [(stest/instrumentable-syms) arg1#]
                            :default     [arg1# arg2#])]
 (try
   (stest/instrument sym-or-syms# opts#)
   ~@body
   (finally
     (stest/unstrument sym-or-syms#)))))

`

虽然并不完美,但它已经很好地为我服务。

关于结束时会发生什么的问题是一个非常好的问题。理想情况下,with-instrumentation 应该具有类似于栈的行为,其中仪器将返回到其先前状态。这是否可以使用 spec 完成?

0
by
...