unit testing - Clojure: determina si una variable está declarada
unit-testing variable-assignment (4)
Dado que no hay un buen soporte de IDE para Clojure, me parece que, dada su estructura flexible, es bueno probar los nombres de métodos y la existencia de nombres de variables antes de probar sus salidas / contenido.
Esto es una locura Realmente quieres una prueba para decir "¡Ups! ¡Olvidaste definir foobar
!" en lugar de solo intentar ejecutar foobar
y ver el mensaje "No se puede resolver el símbolo" de Clojure?
¿Qué ganas de esto? Se pierde la pila de seguimiento, lo que podría ser útil si, por ejemplo, otro nombre le asigna un nombre de función incorrecto a la prueba. Es mucho mejor saber qué línea deletreó foobar que buscar en todo el espacio de nombres de la prueba.
¿Cómo puedo probar si una variable ha sido declarada o asignada (es decir, verificar si se define "a", cuando espero que un programa llame a algún código como este (def a (create-a))?
Y relacionado --- ¿cómo se relaciona la respuesta a esta pregunta con el problema de resolver un símbolo (es decir, una función) que ha sido declarado? Clojure: determina si existe una función
Parece que una variable definida debe poder verificarse en el mismo sentido en que lo hace una función definida, pero descubro que la solución para determinar si existe una función no es suficiente para determinar si existe una variable.
Algún contexto: estoy escribiendo pruebas unitarias para un proyecto de múltiples desarrolladores y quiero asegurarme de que se hayan definido los datos de prueba y los métodos en diferentes clases. Dado que no hay un buen soporte IDE para clojure, me parece que, dada su estructura flexible, es bueno probar los nombres de métodos y la existencia de nombres de variables antes de probar sus salidas / contenido.
Como han dicho otros, resolve
devolverá la var para un símbolo si hay uno definido, o nulo. Además, puede verificar si la var tiene un valor vinculado al uso de bound?
.
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
Puede usar resolver para ver si la variable estaba enlazada / definida:
(resolve ''meaning)
nil
(def meaning 42)
#''user/meaning
(resolve ''meaning)
#''user/meaning
o puede verificarlo booleano, si necesita verdadero / falso:
(boolean (resolve ''meaning))
true
Una forma de hacerlo es usar ns-resolve , por ejemplo:
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...
Tenga en cuenta que si su espacio de nombres califica el símbolo que se va a verificar, entonces lo que pase como primer argumento ( *ns*
en el ejemplo anterior) no importa:
user=> (ns-resolve ''user ''a)
#''user/a
user=> (ns-resolve ''other ''a)
nil
user=> (ns-resolve ''other ''user/a)
#''user/a
La función de resolución mencionada por @tolitius es en realidad una abreviatura de ns-resolve
donde el argumento del espacio de nombres siempre se evalúa como ns , dependiendo del caso de uso, podría ser más útil.