flash-get!を使っているページがreplで動かない
ログイン用の簡単なHTMLを出すページをreplとかで動かそうとしたんだけど
ClassCastException clojure.lang.Var$Unbound cannot be cast to java.util.concurrent.Future clojure.core/deref-future (core.clj:2184)
こんなエラーが出て動かなかった。
print-stack-traceでコードを追っかけてみると
どうやらnoir-sessionのflash-getしてるとこで落ちてる模様
user=> (print-stack-trace *e 30) java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to java.util.concurrent.Future at clojure.core$deref_future.invoke (core.clj:2184) clojure.core$deref.invoke (core.clj:2207) noir.session$flash_get.invoke (session.clj:151) noir.session$flash_get.invoke (session.clj:149) sample01.page$base_layout.doInvoke (page.clj:115) clojure.lang.RestFn.invoke (RestFn.java:442) sample01.page$login_page.invoke (page.clj:146) ...
ググって調べてみるとStackOverflowに
「REPLで動かすときはこうすりゃ動くぜ!でもプロダクションには使わないでね(自分解釈)」
と書いてあったので
(binding [sesh/*noir-session* (atom {:somekey "somevalue"})] (sesh/put! :user "borkdude"))
試してみるもエラーは変わらず。
(binding [sesh/*noir-session* (atom {})] (p/login-page {} {}))
仕方ないので、flash-getのコードを眺めてみると
... (declare ^:dynamic *noir-flash*) (defn flash-put! "Store a value that will persist for this request and the next." [k v] (clojure.core/swap! *noir-flash* assoc-in [:outgoing k] v)) (defn flash-get "Retrieve the flash stored value." ([k] (flash-get k nil)) ([k not-found] (let [in (clojure.core/get-in @*noir-flash* [:incoming k]) out (clojure.core/get-in @*noir-flash* [:outgoing k])] (or out in not-found)))) (defn ^:private noir-flash [handler] (fn [request] (binding [*noir-flash* (atom {:incoming (:flash request)})] (let [resp (handler request) outgoing-flash (:outgoing @*noir-flash*)] (if (and resp outgoing-flash) (assoc resp :flash outgoing-flash) resp))))) ...
あれ、もしかして*noir-session*
じゃなくて*noir-flash*
なんじゃね?
と感じたのでやってみるとうまくいった。
(binding [sesh/*noir-flash* (atom {})] (p/login-page {} {}))
今日はエスパー力高かった。