在Clojure中,如何获取变量和函数所在的命名空间的名称?例如,改进以下代码:
上述问题在于,如果我想更改my-ns的名称,那么我也必须更改namespace-name的定义。
(ns my-ns)
(def namespace-name "my-ns")
上述问题在于,如果我想更改my-ns的名称,那么我也必须更改namespace-name的定义。
(ns my-ns)
(def namespace-name "my-ns")
(def namespace-name (ns-name *ns*))
然而我想警告Clojure的初学者们
(defn namespace-name [] (ns-name *ns*))
对于这个问题的目的来说,这不起作用,因为*ns*是动态绑定的。
当前的命名空间存储在
*ns*
由于您的函数在运行时被评估,因此当您调用它时,您将得到 * ns * 的任何值。所以如果您想要保存它的副本。
*ns*
可以用反引号括起来写,我猜。 - Peter Tillemans(clojure.test/run-tests *ns*)
- Aaron Blenkush要创建和存储命名空间,您可以执行以下操作:
user=> (def working-namespace (create-ns 'my-namespace))
#'user/working-namespace
user=> working-namespace
#<Namespace my-namespace>
user=> (class working-namespace)
clojure.lang.Namespace
你刚刚得到了一个命名空间对象,但我不能告诉你关于它能做什么的太多信息。目前我只知道有一个函数intern可以接受一个命名空间对象。
user=> (intern working-namespace 'my-var "somevalue")
#'my-namespace/my-var
好的,通过这位名叫Michael Kohl的人的帮助,我找到了如何切换到一个变量中保存的命名空间(在此处阅读更多细节)
所以,我们开始吧:
user=> (def working-namespace (create-ns 'my-namespace))
#'user/working-namespace
user=> (in-ns (symbol (str working-namespace) ))
#<Namespace my-namespace>
my-namespace=>
;; notice how it switched to "my-namespace"
;; now if i were to put some other namespace in that variable...
my-namespace=> (ns user)
nil
user=> (def working-namespace (create-ns 'other-namespace))
#'user/working-namespace
;; and switch again, i would get the new namespace
user=> (in-ns (symbol (str working-namespace) ))
#<Namespace other-namespace>
other-namespace=> ; tadaa!
虽然我认为重新分配变量不是Clojure的惯用方式,但你可以将其构建成一个函数,并将命名空间的holder变量作为参数传递。
现在来获取该命名空间内外变量的值。
user=> (intern working-namespace 'some-var "my value")
#'other-namespace/some-var
user=> (var-get (intern working-namespace 'some-var))
"my value"
ns
周围的星号,应该是这样写的:(defmacro defns-name [name] \
(def ~name (ns-name ns)))`。 - Martin Carpenter