如何从另一个命名空间卸载一个函数?

时间:2014-12-11 00:28:37

标签: clojure

我从命名空间learning.greeting

加载函数say-hi
(use 'learning.greeting)

当我尝试在当前(用户)命名空间下重新定义say-hi函数时,我收到错误:

CompilerException java.lang.IllegalStateException: say-hi already refers to: #'learning.greeting/say-hi in namespace: user, compiling:(NO_SOURCE_PATH:1:1) 

那么如何从其他命名空间中卸载该函数呢?

3 个答案:

答案 0 :(得分:4)

如果你想从REPL的另一个命名空间中删除到Var的直接映射,比如说

(ns-unmap 'current-namespace 'local-alias)

示例:

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)

如果使用:rename,则本地别名将与Var的实际名称不同:

(use '[clojure.walk
       :only [keywordize-keys]
       :rename {keywordize-keys keywordize}])

删除指向clojure.walk中的Vars的所有映射:

(doseq [[sym v] (ns-map *ns*)]
  (if (and (var? v)
           (= (.. v -ns -name) 'clojure.walk))
    (ns-unmap *ns* sym)))

答案 1 :(得分:2)

您真的要从say-hi中删除learning.greeting吗?如果没有,在这种情况下使用require可能会更好。而不是(use 'learning.greeting),执行:

(require `[learning.greeting :as lg])

然后,您可以将原始定义称为lg/say-hi,并且可以在当前命名空间中定义新版本,例如如

 (def say-hi [x] (lg/say-hi (list x x))

(我不知道这对于say-hi函数是否有意义,但无论如何,一般意义相同。)

答案 2 :(得分:2)

userequire都有:针对这种情况的:exclude参数:

(use '[learning.greeting :exclude [say-hi]])

或更优选使用要求:

(require '[learning.greeting :refer :all :exclude [say-hi]])

或当您在普通命名空间中工作时,首先将所有这些放在ns表单中:

(ns my-namespace
   (:require [learning.greeting :refer [ function1 function2] :as greeting]