在clojure中依赖于环境的协议/多方法的派遣

Shr*_*rat 6 architecture clojure

我在如何构建我的软件的某个特定部分时遇到了问题.让我们说,我有一个叫做make-temp-dir(和许多其他人)的功能,根据当前的操作系统做一些黑魔法.我希望能够将每个操作系统的这些方法的实现放在一个单独的命名空间中.

首先,我认为协议(如果可能)或多方法是解决这个问题的方法.但是,我从未见过将这些实现与跨多个名称空间的实现一起使用的示例.我无法弄清楚这是如何发挥作用的.

其次,如果我使用协议,我将不得不调用类似的方法

(make-temp-dir current-os arg-1 arg-2)
Run Code Online (Sandbox Code Playgroud)

不知何故,将os作为第一个参数传递给我看起来并不太好.出于语义原因,我希望make-temp-dir根据操作系统做出明智的决定.当然,我可以使用一些宏,并做类似的事情

(doto current-os
  (make-temp-dir arg-1 arg2))
Run Code Online (Sandbox Code Playgroud)

但那感觉不对.

该怎么做?或者我走错了路?任何帮助赞赏.

编辑:好的,非常感谢@kotarak,我设法得到了一些工作.对于任何偶然发现此事的人,请访问https://gist.github.com/2477120.工作正常,我想我会顺其自然.感谢大家.

kot*_*rak 7

(ns your.utils)

(def current-os)

(defmulti make-temp-dir
  (fn [& _] current-os))

(ns your.utils.mac)

(defmethod make-temp-dir :mac-os-x
  [a b]
  (...))

(ns your.utils.win)

(defmethod make-temp-dir :windows
  [a b]
  (...))
Run Code Online (Sandbox Code Playgroud)

在你的启动代码,你必须初始化current-osalter-var-root使用任何的效用函数之前.

(let [os (find-os)]
  (alter-var-root #'current-os (constantly os))
  (require (case os
             :mac-os-x 'your.utils.mac
             :windows  'your.utils.win)))
Run Code Online (Sandbox Code Playgroud)

希望能让你开始.