Reflection 为什么source fn在这种特定情况下找不到源代码?
这种情况很难重现。首先,我创建一个包含以下内容的clj文件:Reflection 为什么source fn在这种特定情况下找不到源代码?,reflection,clojure,namespaces,Reflection,Clojure,Namespaces,这种情况很难重现。首先,我创建一个包含以下内容的clj文件: (ns myns) (defn myfn [x] x) (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)) ) 然后创建第二个clj文件,其中包
(ns myns)
(defn myfn [x] x)
(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))
)
然后创建第二个clj文件,其中包含:
(ns myns)
(defn myfn [x] x)
(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”将恢复匹配行为。我也知道迭代源代码fn有点古怪,但这是我知道的复制行为的最简单方法。我不理解你的结果。通过
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)"
我不明白你的结果。通过
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)"
两种情况之间的一个区别是:
second
,源fn
在REPL的eval步骤中运行;使用take 2
,source fn
在打印步骤中运行(由于懒惰)。两种情况之间的一个区别是:使用second
,source fn
在REPL的eval步骤中运行;使用take 2
,source fn
在打印步骤中运行(由于懒散)。您无法复制,因为您使用的是spyx。如注释中所述,不同之处在于,iterate
返回一个惰性seq,该seq仅在计算完成后打印。spyx通过在评估阶段将其转换为字符串来更改。您无法复制,因为您正在使用spyx。如注释中所述,不同之处在于,iterate
返回一个惰性seq,该seq仅在计算完成后打印。spyx通过在eval阶段将其转换为字符串来改变这一点。