> Is there a way to unregister some names from a namespace without reloading it > ?
This is a bit trickier than one might think. An example illustrates this; Given two files, a.clj... (ns a) (defn stuff-a [] :stuff-a) (defn hello [] :hello) And b.clj... (ns b) (defn stuff-b [] :stuff-b) Say we have an ns 'x which is our running ns which uses 'a and 'b and we wish to move the 'hello function into 'b in the files and then dynamically reload so that 'x now has the correct mapping to 'hello (i.e in 'b) So in the Repl we'll create an empty ns 'x and change to it... user=>(create-ns 'x) #<Namespace x> user=> (in-ns 'x) #<Namespace x> And load the two files with clojure.core/use ('x does not refer to clojure.core so we can see all the ns mapping more clearly)... x=> (clojure.core/use 'a) nil x=> (clojure.core/use 'b) ni So, 'x now sees... (clojure.core/ns-refers 'x) {hello #'a/hello, stuff-a #'a/stuff-a, stuff-b #'b/stuff-b} And 'a and 'b contain... x=> (clojure.core/ns-publics 'a) {hello #'a/hello, stuff-a #'a/stuff-a} x=> (clojure.core/ns-publics 'b) {stuff-b #'b/stuff-b} You've probably guessed it by now - to move 'hello from 'a to 'b we have to; 1.) Move it from file a.clj to b.clj 2.) Re-require and reload 'b 3.) Unmap it in the "refers" of 'x 4.) Re-refer 'b so 'x now sees it in 'b 5.) Unmap it in the "publics" of 'a Here's the "dynamic reload" after 1.)... 2.) Reload 'b... (clojure.core/require 'b :reload) nil x=> (clojure.core/ns-publics 'b) {hello #'b/hello, stuff-b #'b/stuff-b} x=> (clojure.core/ns-publics 'a) {hello #'a/hello, stuff-a #'a/stuff-a} Note that both 'a and 'b now have 'hello loaded but that's ok as 'x still only knows about the version in 'a. 3, 4 and 5.)... x=> (clojure.core/ns-unmap 'x 'hello) nil x=> (clojure.core/refer 'b) nil x=> (clojure.core/ns-unmap 'a 'hello) nil And so finally we have... (clojure.core/ns-publics 'a) {stuff-a #'a/stuff-a} x=> (clojure.core/ns-publics 'b) {hello #'b/hello, stuff-b #'b/stuff-b} x=> (clojure.core/ns-publics 'x) {} x=> (clojure.core/ns-refers 'x) {hello #'b/hello, stuff-a #'a/stuff-a, stuff-b #'b/stuff-b} There still is a problem with this technique - 3.) and 4.) are not atomic, so if 'hello is called between those two steps (which is likely in a busy web server), that invocation will fail. Note that the (ns-remove technique has the same problem, but at a coarser grain level). I think it's worth looking at encapsulating this whole reload procedure into a properly atomically protected transaction as it will be very useful in many server scenarios. This would probably require changes to the namespace functions in core. Any thoughts? Regards, Adrian. On Sat, Aug 29, 2009 at 8:24 AM, Laurent PETIT<laurent.pe...@gmail.com> wrote: > Could some kind of :force true flag be generally interesting for the def > special form ? (:force true would force an unmap first, if necessary) > > 2009/8/29 Vagif Verdi <vagif.ve...@gmail.com> >> >> Thx to all. ns-unmap and remove-ns are what i need. >> >> From my CL experience i was looking for something like unitern. >> > > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---