Clojure:确定是否声明了变量

时间:2011-10-19 22:00:11

标签: unit-testing clojure variable-assignment

我如何测试变量已被声明或分配(即检查是否定义了“a”,当我希望程序调用这样的代码时(def a(create-a))?

相关---这个问题的答案如何解决已经宣布的符号(即函数)的解决问题? Clojure: determine if a function exists

似乎定义的变量应该以与定义的函数相同的方式检查,但我发现确定函数是否存在的解决方案不足以确定变量是否存在。

某些上下文:我正在为多开发人员项目编写单元测试,并希望确保测试数据和不同类中的方法已定义。由于没有好的IDE支持clojure,在我看来,鉴于其结构松散,在测试其输出/内容之前测试方法名称和变量名称是好的。

4 个答案:

答案 0 :(得分:12)

您可以使用resolve查看变量是否已绑定/定义:

 
(resolve 'meaning)
nil

(def meaning 42)
#'user/meaning

(resolve 'meaning)
#'user/meaning

或者您可以布尔检查它,如果您需要true / false:

(boolean (resolve 'meaning))
true

答案 1 :(得分:4)

执行此操作的一种方法是使用ns-resolve,例如:

user=> (def a "hello a")
user=> (ns-resolve *ns* 'a)
#'user/a
user=> (ns-resolve *ns* 'b)
;nil                    ; This assumes b hasn't been defined before...

请注意,如果您对要检查的符号进行命名空间限定,那么您作为第一个参数(上例中的*ns*)传递的内容无关紧要:

user=> (ns-resolve 'user 'a)
#'user/a
user=> (ns-resolve 'other 'a)
nil
user=> (ns-resolve 'other 'user/a)
#'user/a

@tolitius提到的resolve函数实际上是ns-resolve的简写,其中namespace参数始终求值为 ns ,具体取决于用例,它可能更方便

答案 2 :(得分:4)

正如其他人所说,如果有一个符号,则resolve将返回符号的var,或者为零。此外,您可以使用bound?检查var是否具有绑定的值。

user=> (resolve 'foo)
nil
user=> (def foo)
#'user/foo
user=> (resolve 'foo)
#'user/foo
user=> (bound? #'foo)
false
user=> (def foo 5)
#'user/foo
user=> (bound? #'foo)
true

答案 3 :(得分:1)

  

由于没有好的IDE支持clojure,在我看来,   鉴于其结构松散,最好测试方法名称和   变量名称在测试其输出/内容之前存在。

这很坚果。你真的想要一个测试来说“哎呀!你忘了定义foobar!”而不只是尝试运行foobar并看到Clojure的“无法解析符号”消息?

你从中获得了什么?您丢失了堆栈跟踪,例如,如果测试通过其他代码传递了错误的函数名称,那么这可能很有用。更好的是要知道什么行错误拼写foobar比搜索整个测试命名空间。