考慮從新鮮的lein new app arrow-mve
的MVE(最小可行示例)命名空間中的以下功能。功能extract-one
是公開的,功能extract-two
是私人的。我只包括了完整性和爲它在我的問題真實entailed遠程可能性main-
功能:線程箭頭clojure.test中的私人defence
(ns arrow-mve.core
(:gen-class))
(defn extract-one [m]
(-> m :a))
(defn- extract-two [m]
(-> m :a))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!"))
在我的並行測試的命名空間,我可以測試這些功能如下。我可以通過直接調用或使用箭頭線宏->
來測試公共函數extract-one
。另外請注意,在直接調用中,我沒有任何提及私有函數extract-two
的完整Var
的問題。這些測試都通過了:
(ns arrow-mve.core-test
(:require [clojure.test :refer :all]
[arrow-mve.core :refer :all]))
(deftest test-one-a
(is (= 1 (extract-one {:a 1, :b 2}))))
(deftest test-one-b
(is (= 1 (-> {:a 1, :b 2}
extract-one))))
(deftest test-two-a
(is (= 1 (#'arrow-mve.core/extract-two
{:a 1, :b 2}))))
但我得到一個編譯錯誤,當我嘗試調用私有函數extract-two
用箭頭宏:
(deftest test-two-b
(is (= 1 (-> {:a 1, :b 2}
#'arrow-mve.core/extract-two))))
$ lein test
Exception in thread "main" java.lang.RuntimeException: Unable to resolve var: arrow.mve.core/extract-two in this context, compiling: (arrow_mve/core_test.clj:10:12) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6875) at clojure.lang.Compiler.analyze(Compiler.java:6669) at clojure.lang.Compiler.analyze(Compiler.java:6625)
事情變得更怪的時候,我讓測試更復雜一點。
(deftest test-two-b
(is (= {:x 3.14, :y 2.72}
(-> {:a {:x 3.14, :y 2.72}, :b 2}
#'arrow-mve.core/extract-two))))
$ lein test
Exception in thread "main" java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.Symbol, compiling:(arrow_mve/core_test.clj:18:10) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6875) at clojure.lang.Compiler.analyze(Compiler.java:6669) at clojure.lang.Compiler.analyzeSeq(Compiler.java:6856)
再次,測試通過在直接呼叫形式:
(deftest test-two-b
(is (= {:x 3.14, :y 2.72}
(#'arrow-mve.core/extract-two
{:a {:x 3.14, :y 2.72}, :b 2}))))
我懷疑問題是通過deftest
宏觀鏈,is
的限制,讀者宏#'
爲Var
和箭頭宏,並想知道它是否是由設計或潛在的錯誤。當然,在我真正的應用程序(不是這個MVE)中,我有很長很長的調用鏈,使得使用箭頭宏非常可取。