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

欢迎!请在关于页面查看有关如何使用本功能的更多信息。

0
规范

目前,{{instrument}} 和 {{uninstrument}} 对于测试和开发的无条件配置非常出色。我还可以为一个特定的代码片段运行 instrument。例如,我想有一个带有一些存根或一些重写的测试。目前我需要执行 instrument 和 uninstrument,我更喜欢有一个 with-instrument 宏为我执行明显的 try/finally 块。

3 个回答

0

评论者:alexmiller

因此(就像大多数事情一样),明显的事情并不明显。 :)

调用 instrument 有几种方式

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

这里的数字是可变的。同样,其他 with-style 宏中的 "body" 通常也是可变参数。解析这两个可变参数是模糊的。

你提到了 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))))

`

在对已经 instrumented 的内容进行考虑的程度可能会有一些有趣的想法。你是要取消对 instrumented 的配置,还是尝试将配置恢复到之前的状态(其中一些内容可能已经被 instrumented)?

0

评论者:dsg

以下是我一直在使用的一种实现,这并不是必须使用的,但我想它有助于解决参数的模糊性问题。

`
(defmacro 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 应该具有类似于堆栈的语义,其中仪器将返回到其先前的状态。这是否可以用规范来实现呢?

0
by
参考: https://clojure.atlassian.net/browse/CLJ-2015 (由 lvh 报告)
...