いいえ、実際にはコード内で直接「使用」を使用したくありません。Use はそれが呼び出される名前空間全体を変更するため、ほとんど予測できない方法でコードが壊れる可能性があります。
代わりに、次のことを行う必要があります。ロギング インターフェイス (プロトコル) を実装し、config.clj で設定したものをキーワードとしてディスパッチする「メタ コンストラクター」を記述します。コード例
(defprotocol ILog
(save-data [this msg] "Logs message in msg."))
(defn create-file-log
"Returns an object implementing ILog, opens and flushes java.io.File file."
[file]
(let [f ... ;; create file writer here
]
(reify ILog
(save-data [this msg] ;; Write code that writes data to file here
))))
;; create other implementations like database here or elsewhere
(defn create-log
"Creates a log of of the type passed in type-kw."
[type-kw]
(case type-kw
:file (create-file-log "./app-log.txt")
;; other types
))
これで、構成ファイルに設定されているキーワードを使用して create-log を呼び出すだけで、返されたオブジェクトをロギングを行う必要がある関数に渡すことができます。明らかに、グローバル オブジェクトとして定義することもできますが、それはお勧めしません。
最終的には、設定で目的のロギング方法のキーワード (type-kw) を設定するだけでなく、ファイル名やデータベース uri などの他のパラメーターも設定して、次のようなものを渡すことができるようにする必要があります。
{:log-method :file
:data {:fname "app-log.txt"}}
or
{:log-method :db
:data {:uri "....
...この構造体を使用して reify コンストラクター create-file-log、create-db-log などのパラメーターを取得する create-log 関数に。
編集:
switch ステートメントが気に入らないため、マルチメソッドでそれを行う方法は次のとおりです。
(defmulti create-log :logging-method)
(defmethod create-log :file
[arg-map]
(let [file (java.io.File. (:fname arg-map))]
(if (.exists file)
...
次に、config.cljにエントリを作成するだけです
{...
:log {:logging-method :file
:fname "./log-file.txt"}}
新しいロギング タイプを作成するには、上記のような引数マップと create-log のコンストラクタ メソッドを想像するだけです。