(require '[taoensso.truss :as truss])
假設我們有一張描述i circle的地圖。的圓始終具有中心,但是可以通過任一的直徑或半徑來描述:使用Taoensso Truss在地圖上的可選密鑰下驗證內容
{:center [1, 2] :diameter 10}
{:center [1, 2] :radius 5}
上述兩個圓圈描述相同的圓。
所以說,我們有一個函數,期望一個圓形地圖作爲它的輸入,我們怎麼能最好地堅持這與桁架?代碼的開始可能看起來像:
(defn circle-tosser
[circle-map]
(truss/have map? circle-map)
(truss/have number? :in (:center circle-map))
(str "Tossing " circle-map))
(circle-tosser {:center [1, 2] :radius 5})
;; => "Tossing {:center [1 2], :radius 5}"
的問題當然是,我們不能只是直線上升斷言,這些鍵的值有certine性質,因爲它們不存在neccicerily的。例如下面的聲明將要求這兩個鍵是存在在同一時間:
(defn circle-tosser
[circle-map]
(truss/have map? circle-map)
(truss/have number? :in (:center circle-map))
(truss/have number? (:diameter circle-map))
(truss/have number? (:radius circle-map))
(str "Tossing " circle-map))
(circle-tosser {:center [1, 2] :diameter 10}) ; Unhandled Exception
(circle-tosser {:center [1, 2] :diameter 10 :radius 5})
;; => "Tossing {:center [1 2], :diameter 10, :radius 5}"
然後,您可以開始寫東西像
(defn circle-tosser
[circle-map]
(truss/have map? circle-map)
(truss/have number? :in (:center circle-map))
(when (contains? circle-map :diameter)
(truss/have number? (:diameter circle-map)))
(when (contains? circle-map :radius)
(truss/have number? (:radius circle-map)))
(str "Tossing " circle-map))
(circle-tosser {:center [1, 2] :diameter 10})
;; => "Tossing {:center [1 2], :diameter 10}"
但開始變得過於冗長,無法讀取,這因爲提供了可訪問的文檔(以代碼的形式),這是不幸的,是桁架目的的一部分。
也許你可以想出一個更好的方法來解決這個問題?
我明白你的觀點對圓圈的例子是否有效。也許我通過使用非現實世界的例子做錯了。想一想,例子是「我們有一個配置圖,它有許多不同的可選鍵,我們要驗證這些值」,就像leiningen project.clj。你認爲我應該用這個例子來發表一個新帖子嗎? – Rovanion