スチュアートの話から私が理解していることは、次のようなものです。
(ns state.core)
(defn create-user-module [] (atom []))
(defn add-user [module user]
(swap! module conj user))
(defn get-users [module]
@module)
状態を操作する関数はパラメーターとしてそれを取得することを期待しているため、「コア」にグローバル状態はありません。これにより、テストごとに「ユーザー モジュール」の新しいインスタンスを作成できるため、テストが容易になります。また、このモジュールのクライアントは、create-user-module 関数で取得したものを気にする必要はありません。検査せずに渡すだけでよいため、必要なときにいつでもユーザー モジュールの実装を変更できます。Stuart は、複数の実装を行う場合に、これらのモジュールのプロトコルを作成することについても話します。
あなたの質問に答えようとすると、リング アダプターは単なる 1 つのパラメーターの関数であり、compojure は単なるルーティング ライブラリであるため、次のようなクロージャーを使用して Web アプリを作成できます。
(ns state.web
(:use compojure.core)
(:require [state.core :as core]))
(defn web-module [user-module]
(routes
(GET "/all" [] (core/get-users user-module))))
これで、web-module を呼び出して webapp を作成し、必要な依存関係をパラメーターとして渡すことができます。もちろん、正しいユーザー モジュールを使用して Web アプリを作成する人がまだ必要なので、必要なのはすべてを結び付ける「メイン」関数だけです。
(ns state.main
(:require state.core
state.web)
(:use ring.adapter.jetty))
(defn start []
(let [user-module (state.core/create-user-module)
web-module (state.web/web-module user-module)]
(run-jetty web-module {:port 3000 :join? false})))
(defn stop [app]
(.stop app))
start
main
アプリのメソッドから呼び出されます。これは、lein-run プラグインに切り替える必要があることを意味します。
さて、あなたがinit
(私が推測する lein ring プラグインから) について質問していることを考えると、Web アプリケーションをコンテナーにデプロイすることを計画していると思います。lein ring プラグインは Java サーブレット fw 制約内で動作する必要があり、ハンドラーは最終的に Java サーブレットにコンパイルされるため、おそらく実行できる最善の方法は次のようなものです。
(ns state.web
(:use compojure.core)
(:require [state.core :as core]))
(def module-deps (atom {})
(defn init-app [] (swap! module-deps conj [:user-module (core/create-user-module)]))
(defroutes web-module []
(GET "/all" [] (core/get-users (:user-module @module-deps))))
これは、コアの名前空間がテストしやすいことを意味しますが、Web 名前空間にはまだグローバルな状態がありますが、それは「適切に」カプセル化されており、Java コンテナーを使用する必要がある場合はおそらく十分であると思います。
これは、ライブラリがフレームワークよりも「優れている」理由のもう 1 つの議論です :)