6

我在如何构建我的软件的特定部分时遇到了问题。可以说,我有一个名为make-temp-dir(和许多其他)的函数,它根据当前的操作系统执行一些黑魔法。我希望能够将每个操作系统的这些方法的实现放在单独的命名空间中。

首先,我相信协议(如果可能的话)或多方法是解决这个问题的方法。但是,我从未见过将这些与跨越多个命名空间的实现一起使用的示例。而且我无法弄清楚这是如何解决的。

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

(make-temp-dir current-os arg-1 arg-2)

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

(doto current-os
  (make-temp-dir arg-1 arg2))

但这感觉不对。

这应该怎么做?还是我走错路了?任何帮助表示赞赏。

编辑:好的,非常感谢@kotarak,我设法得到了一些工作。对于任何偶然发现的人,https ://gist.github.com/2477120 。它工作正常,我想我会去的。谢谢大家。

4

2 回答 2

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

在您的启动代码中,您必须在current-os使用alter-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)))

希望这能让你开始。

于 2012-04-23T15:53:29.060 回答
1

我不能肯定地说,但听起来你最终可能会重新发明 Java 为你提供的轮子。试试https://github.com/Raynes/fs来方便地包装一些 Java 提供的超出 clojure.java.io ( http://clojuredocs.org/clojure_core/clojure.java.io )基本工具的东西.

如果您的问题超出了特定于操作系统的分支到特定于环境的配置值,您可能还会发现https://github.com/drakerlabs/milieu很有用。我将这段代码作为我们在 Draker 的专有项目的一部分编写,我们最近刚刚将它作为免费软件发布。我们还没有正式向社区宣布它,但它在 Clojars 中并且可以使用。反馈表示赞赏!推动其创建的概念是开发/测试/登台/生产等意义上的环境,但我看不出它为什么不能用于为不同的操作系统环境配置变量。

于 2012-04-23T21:41:50.050 回答