2017-10-10 9 views
0

je le code suivantrésolution se comporte différents dans REPL et -main

(ns clojure-noob.core 
    (:gen-class)) 

(defn -main [& args] 
    (defn A [x] (str x "a")) 
    (println (A "."))      ; .a 
    (println A)        ; some object 
    (println (symbol "A"))     ; just A 
    (println (resolve(symbol "A")))   ; nil 
    (println ((resolve(symbol "A")) ".")) ; nullpointer exception 
) 

Si j'entre les lignes (en commençant par (defn A ...) un par un dans rempl, ils se comportent comme prévu. Le dernier

(println ((resolve(symbol "A")) ".")) 

appelle A sur "." c'est-à-dire qu'il ajoute la lettre a. Mais le tout appelé avec lein run dans leiningen donne nil sur le second dernier et une exception de pointeur null sur la dernière ligne, c'est-à-dire resolve ne résout pas comme prévu.

Qu'est-ce que je fais mal? Quelle est la différence entre lein repl et lein run?

Répondre

1

La réponse courte est que votre espace de noms actuel est différent lorsque resolve est en cours d'évaluation dans lein repl par rapport lein run et resolve travaux sur l'espace de noms en cours. Le resolve docstring:

même que (ns-résolution * ns * symbole) ou (ns-resolve * ns * symbole & env)

*ns* est obligatoire à tout ce que l'espace de noms en cours est .

Vous pouvez voir la différence en ajoutant (println "current ns is" *ns*).

En utilisant ns-resolve et passer l'espace de noms explicitement pour rendre votre travail de code dans les deux cas:

(println (ns-resolve 'clojure-noob.core (symbol "A"))) 
(println ((ns-resolve 'clojure-noob.core (symbol "A")) ".")) 

En aparté, vous ne généralement voyez pas imbriquéedefn-à-dire votre fonction A pourrait être définie en dehors/avant la fonction -main.

+0

Merci beaucoup! Ça fonctionne maintenant. – Rat62

+0

@ Rat62 De cela répond à votre question, vous devez le marquer comme la réponse acceptée m – Carcigenicate