Can't get Ring to reload namespace

86 views
Skip to first unread message

Neill Alexander

unread,
Feb 23, 2010, 5:05:48 PM2/23/10
to Clojure
Can anyone help me to work out why Ring isn't reloading my namespace?

;;------------------------------------
(ns com.nwalex.sponge.server.core
[:require
[ring.adapter.jetty :as jetty]
[ring.middleware.reload :as reload]])


(defn app [req]
{:status 200
:headers {"Content-Type" "text/html"}
:body "Hello World from Ring"})

(def with-reload-app (reload/wrap-reload app
'(com.nwalex.sponge.server.core)))

;;------------------------------------

I start swank using "lein swank", then connect from Emacs using M-x
slime-connect. I then kick off the server by running:

com.nwalex.sponge.server.core> (def s (jetty/run-jetty with-reload-app
{:port 8080 :join false}))

That's all fine - I can see the output on the browser when I navigate
to http://localhost:8080. But I was expecting to be able to change the
text in :body, save and re-compile, and then see the updated text in
the browser on refresh. It doesn't seem to be working. Can anyone tell
me why?

James Reeves

unread,
Feb 23, 2010, 6:30:26 PM2/23/10
to Clojure

On Feb 23, 10:05 pm, Neill Alexander <neillalexan...@gmail.com> wrote:
> Can anyone help me to work out why Ring isn't reloading my namespace?
>
> ;;------------------------------------
> (ns com.nwalex.sponge.server.core
>   [:require
>    [ring.adapter.jetty :as jetty]
>    [ring.middleware.reload :as reload]])
>
> (defn app [req]
>   {:status  200
>    :headers {"Content-Type" "text/html"}
>    :body    "Hello World from Ring"})
>
> (def with-reload-app (reload/wrap-reload app
> '(com.nwalex.sponge.server.core)))

Basically because wrap-reload is a function, so app is evaluated
before it is passed to wrap-reload.

What you probably want is to encase app in an anonymous function
before passing it in, e.g. #(app %).

- James

Mark McGranaghan

unread,
Feb 23, 2010, 6:55:28 PM2/23/10
to Clojure
> Basically because wrap-reload is a function, so app is evaluated
> before it is passed to wrap-reload.

Right. To elaborate, the code "(reload/wrap-reload app '(ns1 ns2))"
invokes the wrap-reload function with the current value of the "app"
Var, which is a specific and immutable function. The reload middleware
may subsequently reload the namespaces and therefore change the value
of the app Var, but the value that is used to invoke (app req) within
the middleware remains unchanged.

I'd therefore suggest passing a Var instead of a function:

(reload/wrap-reload (var app) '(ns1 ns2))

In this way, each time app is invoked within the middleware, it first
goes to get the current value of the app var and then uses that value
to evaluate the request argument; i.e. the reload works.

Note that if the implementation of app itself never changes, only the
functions that it in turn calls, then the (var app) bit becomes
unnecessary.

HTH,
- Mark

James Reeves

unread,
Feb 23, 2010, 8:00:43 PM2/23/10
to Clojure
Ah yep, (var app) is probably a better idea than #(app %).

- James

Neill Alexander

unread,
Feb 24, 2010, 3:50:41 AM2/24/10
to Clojure
Great, that makes sense. Thanks very much guys.
Reply all
Reply to author
Forward
0 new messages