问题
I load a function say-hi from namespace learning.greeting
(use 'learning.greeting)
When I try to re-defn the say-hi function under the current (user) namespace, I got the error:
CompilerException java.lang.IllegalStateException: say-hi already refers to: #'learning.greeting/say-hi in namespace: user, compiling:(NO_SOURCE_PATH:1:1)
So how to unload the function from other namespaces?
回答1:
If you want to get rid of a direct mapping to a Var from another namespace at the REPL, say
(ns-unmap 'current-namespace 'local-alias)
Example:
user=> (ns-unmap *ns* 'reduce)
nil
user=> (reduce + 0 [1 2 3])
CompilerException java.lang.RuntimeException: Unable to resolve symbol: reduce in this context, compiling:(NO_SOURCE_PATH:2:1)
Local alias will differ from the actual name of the Var if :rename was used:
(use '[clojure.walk
:only [keywordize-keys]
:rename {keywordize-keys keywordize}])
To remove all mappings pointing at Vars in clojure.walk:
(doseq [[sym v] (ns-map *ns*)]
(if (and (var? v)
(= (.. v -ns -name) 'clojure.walk))
(ns-unmap *ns* sym)))
回答2:
Do you really want to remove say-hi from learning.greeting? If not, it might be better to use require in this situation. Instead of (use 'learning.greeting), execute:
(require `[learning.greeting :as lg])
Then you can refer to the original definition as lg/say-hi, and you can define a new version in the current namespace, e.g. as
(def say-hi [x] (lg/say-hi (list x x))
(I don't know whether that makes sense for the say-hi function, but the general point is the same regardless.)
回答3:
both use and require have an :exclude parameter for just this situation:
(use '[learning.greeting :exclude [say-hi]])
or more preferably use require:
(require '[learning.greeting :refer :all :exclude [say-hi]])
or when you are working in a normal namespace putting all this in the ns form is preferred:
(ns my-namespace
(:require [learning.greeting :refer [ function1 function2] :as greeting]
来源:https://stackoverflow.com/questions/27413389/how-to-unload-a-function-from-another-namespace