2011-10-19 3 views
12

Comment puis-je tester si une variable a été déclarée ou affectée (c.-à-d. Vérifier si "a" est défini, quand je m'attends à ce qu'un programme appelle un code comme ceci (defa a))?Clojure: Détermine si une variable est déclarée

et connexes --- comment la réponse à cette question ont trait au problème de la résolution d'un symbole (par exemple une fonction) qui a été déclarée? Clojure: determine if a function exists

Il semble comme une variable définie devrait être vérifiable dans le même sens qu'une fonction définie est, mais je trouve que la solution pour déterminer si une fonction existe n'est pas suffisante pour déterminer si une variable existe

Un contexte: J'écris des tests unitaires pour un projet multi-développeur, et je veux m'assurer que les données de test et les méthodes dans différentes classes ont été définies. Comme il n'y a pas de bon support IDE pour clojure, il me semble que, vu sa structure lâche, il est bon de tester les noms des méthodes et l'existence des noms de variables avant de tester leurs sorties/contenus.

+0

Je vois que 'résoudre 'est déjà mentionné dans le message auquel vous avez un lien, pouvez-vous décrire où cela ne correspond pas à votre cas d'utilisation? – Paul

+0

Oui.Je l'ai remarqué mais je me posais des questions sur l'utilisation de la méthode qoute par rapport à la méthode du double qouted dans l'exemple lié. En quoi est-ce différent de (résolution (symbole "my-function-isnt-a-symbol")) utilisé pour résoudre des fonctions? – jayunit100

+1

duplicata possible de [Comment déterminer si le symbole est borné (var défini)?] (Http://stackoverflow.com/questions/4908071/how-to-determine-if-symbol-is-bounded-var-defined) –

Répondre

12

Vous pouvez utiliser resolve pour voir si la variable était liée/définie:

(resolve 'meaning) 
nil 

(def meaning 42) 
#'user/meaning 

(resolve 'meaning) 
#'user/meaning 

ou vous pouvez booléen vérifier, si vous avez besoin vrai/faux:

(boolean (resolve 'meaning)) 
true 
+0

Oui, c'est la bonne réponse :) – jayunit100

4

Une façon de faire est d'utiliser ns-resolve, par exemple:

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... 

Notez que si vous namespace-qualifier le symbole à vérifier alors ce que vous passez comme premier argument (*ns* dans l'exemple ci-dessus) n'a pas d'importance:

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

la fonction resolve mentionnée par @tolitius est en fait un raccourci pour ns-resolve où l'argument namespace évalue toujours ns, selon le cas d'utilisation, il pourrait être plus pratique.

4

Comme d'autres ont dit , resolve retournera le var pour un symbole s'il y en a un, ou nul. En outre, vous pouvez vérifier si la variable a une valeur liée en utilisant 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 
1

Comme il n'y a pas un bon support IDE pour clojure il me semble que, compte tenu de sa structure lâche, il est bon de tester les noms de méthodes et noms variables existence avant de tester leurs sorties/contenu.

Ceci est des noix. Vous voulez vraiment un test pour dire "Oups! Vous avez oublié de définir foobar!" au lieu de simplement essayer de lancer foobar et de voir le message "Impossible de résoudre le symbole" de Clojure?

Que gagnez-vous? Vous perdez la trace de pile, ce qui peut être utile si, par exemple, le test est passé le mauvais nom de la fonction par un autre code. Il vaut mieux savoir quelle ligne est mal orthographiée foobar que de chercher dans tout votre espace de noms de test.

+0

bien, "incapable de résoudre le symbole foobar" pourrait être parce qu'un espace de noms n'a pas été importé correctement. un test unitaire qui importe correctement tous les noms vérifie que les symboles non résolus sont, en fait, dus à des erreurs d'importation ns, plutôt que des ressources vraiment manquantes ... (travaillait récemment sur une base de code PHP massive, et a trouvé que les tests unitaires pour les variables, les méthodes et les ressources étaient des sauveteurs absolus sur des projets multi-développeurs avec des dépendances externes et des espaces de noms multiples). – jayunit100

Questions connexes