2017-06-09 1 views
1

Diese Situation ist ziemlich schwierig zu reproduzieren. Zuerst erstelle ich eine Datei mit CLJ:Warum kann source-fn in diesem speziellen Fall keinen Quellcode finden?

(ns myns) 

(defn myfn [x] x) 

Dann erstelle ich eine zweite CLJ Datei enthält:

(ns myns2 
(:require [myns :as m] 
      [clojure.repl :as repl])) 

(comment 

(second (iterate repl/source-fn 'm/myfn)) 

(take 2 (iterate repl/source-fn 'm/myfn)) 

) 

Dann beginne ich eine REPL und die zweite Datei in dem laden. Schließlich werte ich beide Kommentare aus, indem ich sie an die REPL sende. Der erste Ausdruck ergibt "(defn myfn [x] x)" wie erwartet. Der zweite Ausdruck ergibt jedoch '(m/myfn nil). Was geht hier vor sich?

Beachten Sie, dass die vollständige Qualifizierung von 'm/myfn als' myns/myfn das Übereinstimmungsverhalten wiederherstellt. Ich verstehe auch, dass das Iterieren von Source-Fn irgendwie verrückt ist, aber es ist die einfachste Art, wie ich das Verhalten reproduzieren kann.

+1

Ein Unterschied zwischen den beiden Fällen: mit 'second',' source-fn' während der eval läuft Schritt der REPL; mit 'take 2' läuft' source-fn' während des Druckschrittes (wegen Faulheit). – ez121sl

Antwort

0

Ich verstehe Ihre Ergebnisse nicht. Laufen aus einer Datei über lein test, erhalte ich unterschiedliche Ergebnisse:

(newline) 
(def iii (iterate inc 0)) 
(spyx (nth iii 0)) 
(spyx (nth iii 1)) 
(spyx (nth iii 2)) 

(defn foo [x] 42) 
(def bar (repl/source-fn 'foo)) 
(newline) 
(spyx bar) 

(newline) 
(spyx (take 1 (iterate repl/source-fn 'foo))) 
(spyx (take 2 (iterate repl/source-fn 'foo))) 

(newline) 
(spyx (first (iterate repl/source-fn 'foo))) 
(spyx (second (iterate repl/source-fn 'foo))) 

mit den Ergebnissen:

(nth iii 0) => 0 
(nth iii 1) => 1 
(nth iii 2) => 2 

bar => "(defn foo [x] 42)" 

(take 1 (iterate repl/source-fn (quote foo))) => (foo) 
(take 2 (iterate repl/source-fn (quote foo))) => (foo "(defn foo [x] 42)") 

(first (iterate repl/source-fn (quote foo))) => foo 
(second (iterate repl/source-fn (quote foo))) => "(defn foo [x] 42)" 
+0

Sie können nicht reproduzieren, weil Sie Spyx verwenden. Wie in den Kommentaren angemerkt, besteht der Unterschied darin, dass "iterate" einen lazy seq zurückgibt, der erst nach der Auswertung gedruckt wird. Spyx ändert dies, indem es während der Eval-Phase in eine Zeichenkette umgewandelt wird. – amalloy

Verwandte Themen