我如何测试变量已被声明或分配(即检查是否定义了“a”,当我希望程序调用这样的代码时(def a(create-a))?
相关---这个问题的答案如何解决已经宣布的符号(即函数)的解决问题? Clojure: determine if a function exists
似乎定义的变量应该以与定义的函数相同的方式检查,但我发现确定函数是否存在的解决方案不足以确定变量是否存在。
某些上下文:我正在为多开发人员项目编写单元测试,并希望确保测试数据和不同类中的方法已定义。由于没有好的IDE支持clojure,在我看来,鉴于其结构松散,在测试其输出/内容之前测试方法名称和变量名称是好的。
答案 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比搜索整个测试命名空间。