最初に clojure.edn を使用し、特に clojure.edn/read を使用します。例)
(use '(clojure.java [io :as io]))
(defn from-edn
[fname]
(with-open [rdr (-> (io/resource fname)
io/reader
java.io.PushbackReader.)]
(clojure.edn/read rdr)))
io/resource を使用した config.edn のパスに関しては、これに対処する唯一の方法です。おそらく実行時に変更された config.edn を保存したいので、ファイル リーダーとライターのパスが次のような修飾されていないファイル名で構成されているという事実に依存したい場合があります。
(io/reader "where-am-i.edn")
デフォルトは
(System/getProperty "user.dir")
実行時に構成を変更したいという事実を考慮すると、このようなパターンを実装できます (ラフスケッチ)
;; myapp.userconfig
(def default-config {:k1 "v1"
:k2 2})
(def save-config (partial spit "config.edn"))
(def load-config #(from-edn "config.edn")) ;; see from-edn above
(let [cfg-state (atom (load-config))]
(add-watch cfg-state :cfg-state-watch
(fn [_ _ _ new-state]
(save-config new-state)))
(def get-userconfig #(deref cfg-state))
(def alter-userconfig! (partial swap! cfg-state))
(def reset-userconfig! #(reset! cfg-state default-config)))
基本的に、このコードはグローバルではないアトムをラップし、それへの set および get アクセスを提供します。現在の状態を読み取り、sth を使用してアトムのように変更できます。のように(alter-userconfig! assoc :k2 3)
。グローバル テストでは、リセットできます。userconfig を変更し、さまざまな userconfig をアプリケーションに挿入します(alter-userconfig! (constantly {:k1 300, :k2 212}))
。
userconfig を必要とする関数は (defn do-sth [cfg arg1 arg2 arg3] ...) のように記述でき、default-userconfig、testconfig1,2,3 などのさまざまな構成でテストできます。 user-panel は get/alter..! を使用します。機能。
また、上記の let は、userconfig が変更されるたびに .edn ファイルを自動的に更新するウォッチを userconfig にラップします。これをしたくない場合は、save-userconfig を追加できます。アトムの内容を config.edn に吐き出す関数。ただし、私の意見では、上記のパターンの型を破る (カスタム フォント サイズが変更された後に GUI を再レンダリングするなど) アトムにさらにウォッチを追加する方法を作成することもできます。
代わりに、より大きなアプリケーションを扱っている場合、より良いアプローチは、userconfig のプロトコルを (let ブロックのような同様の関数で) 定義し、ファイル、データベース、atom (または任意のもの) のさまざまなコンストラクターで実装することです。テスト/さまざまな使用シナリオの必要性) reify または defrecord を利用します。このインスタンスはアプリケーション内で渡される可能性があり、すべての状態操作/io 関数は、グローバルなものの代わりにそれを使用する必要があります。