Clojure: ссылается на имя пространства имен - PullRequest
12 голосов
/ 21 сентября 2010

В Clojure, как мне получить имя пространства имен, в котором названы переменные и функции?Например, улучшается следующее:

(ns my-ns)

(def namespace-name "my-ns")

Проблема с вышесказанным заключается в том, что если я хочу изменить имя my-ns, я должен также изменить определение namespace-name

Ответы [ 4 ]

13 голосов
/ 22 сентября 2010

Простая модификация ответа Артура работает хорошо.

(def namespace-name (ns-name *ns*))

Однако я хочу предупредить начинающих Clojure о том, что

(defn namespace-name [] (ns-name *ns*))

не будет работать для целей этого вопроса, так как * ns * связан динамически.

8 голосов
/ 21 сентября 2010

текущее пространство имен хранится в

*ns* 

, так как ваша функция оценивается во время выполнения, вы получите то, что когда-либо будет иметь значение * ns * при вызове.

так что если вы хотите сохранить его копию.

3 голосов
/ 22 сентября 2010

, чтобы создать и сохранить пространство имен, вы можете сделать:

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
1 голос
/ 23 сентября 2010

Хорошо, с помощью этого парня, Майкла Коля, я узнал, как переключиться на пространство имен, содержащееся в переменной (, читайте здесь для получения более подробной информации )

, так что здесьмы идем:

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!

, хотя я не думаю, что переназначение переменных - это идиоматическое замыкание, вы можете встроить это в функцию, которая теперь получает держатель var для пространства имен как параметр

, чтобыполучить значение переменной var и вне этого пространства имен

user=> (intern working-namespace 'some-var "my value")
#'other-namespace/some-var

user=> (var-get (intern working-namespace 'some-var))
"my value"
...