如何访问当前命名空间的名称?

How do I access the name of the current namespace?

似乎 *ns* 对象在 Clojure 下一直可用,但在 ClojureScript 下不可用。是否有其他方法来访问当前命名空间的名称?

动机

我有很多电话,例如

(define-subscription ::something :other-namespace/something)

其中两次出现的 something 是多余的。我希望能够以 (define-sub 'something) 等更简洁的形式编写此内容,但为了将缩短的形式转换为完整形式,我需要有一种方法来引用关键字 ::something 而不使用 :: 语法糖。 仅在命名空间名称中进行硬编码是可能的,但感觉并不令人满意。

使用宏应该可以做到:

(defmacro defsub [n]
    (let [x# (name n)]
        `(define-subscription (keyword ~x#) (keyword "other" ~x#))))

(defsub blah)

您可以阅读与您感兴趣的命名空间的 var 关联的元数据:

(defn get-current-namespace []
    (-> #'get-current-namespace meta :ns))

或者,如果您不想在命名空间本身中声明此函数,但需要将其作为实用方法,您可以创建一个类似的方法:

(defn namespace-of-var [a-var]
    (-> a-var meta :ns))

你可以这样称呼:

cljs.user> (def a "hello!")
cljs.user> (namespace-of-var #'a)
cljs.user

实际上,您可以从另一个函数调用 namespace-of-var 函数,将函数自己的名称作为 var 参数传递:

(defn function-in-another-namespace []
    (let [current-namespace (namespace-of-var #'function-in-another-namespace)]
        (prn (str "current namespace: " current-namespace))))