为什么source-fn在这种特定情况下无法找到源代码?

时间:2017-06-09 21:00:05

标签: reflection clojure namespaces

重现这种情况非常棘手。首先,我创建一个包含以下内容的clj文件:

(ns myns)

(defn myfn [x] x)

然后我创建了第二个包含以下内容的clj文件:

(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))

)

然后我启动一个REPL并加载第二个文件。最后,我通过将它们发送到REPL来评估这两个评论。第一个表达式将按预期产生"(defn myfn [x] x)"。然而,第二个表达式产生'(m/myfn nil)。这是怎么回事?

请注意,将'm / myfn完全限定为'myns / myfn会恢复匹配行为。另外我理解迭代source-fn有点古怪,但这是我知道的重现行为的最简单方法。

1 个答案:

答案 0 :(得分:0)

我不明白你的结果。通过lein test从文件运行,我得到了不同的结果:

(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)))

结果:

(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)"