2010-09-21 20 views
9

En Clojure, ¿cómo obtengo el nombre del espacio de nombres en el que se nombran las variables y funciones? Por ejemplo, la mejora de los siguientes:Clojure: haciendo referencia al nombre del espacio de nombres

(ns my-ns) 

(def namespace-name "my-ns") 

El problema con lo anterior es que si quiero cambiar el nombre de mis-ns, tengo que cambiar la definición de espacio de nombres, nombre, así

Respuesta

11

Una simple modificación de la respuesta de Arthur funciona bien.

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

Sin embargo, quiero advertir a los principiantes que Clojure

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

no funcionará para los fines de esta pregunta, ya ns * * se une de forma dinámica.

+2

Pero algo a lo largo de la línea (defmacro defns-name [name]' (def ~ name (ns-name * ns *))) y luego call (defns-name namespace-name) funcionaría. –

+0

Markdown comió las estrellas alrededor de 'ns' en Nicolas comentario anterior: debería leer:' (defmacro defns-name [nombre] \ '(def ~ nombre (ns-name * ns *)))'. –

6

la espacio de nombres actual se almacena en

*ns* 

ya que su función se evalúa en tiempo de ejecución que se obtiene lo que cada vez que el valor de NS * * es cuando usted lo llama.

así que si desea guardar una copia de la misma.

+0

¿Quiere decir (def espacio de nombres de nombres (NS-name \ * ns \ *))? – chris

+0

Escribo * ns * y aparece como cursiva? ¿Cómo escribo esto para que así lo muestre literalmente? –

+0

ahh lo hizo de nuevo! * ns * –

3

para crear y almacenar un espacio de nombres, que puede hacer:

user=> (def working-namespace (create-ns 'my-namespace)) 
#'user/working-namespace 

user=> working-namespace 
#<Namespace my-namespace> 

user=> (class working-namespace) 
clojure.lang.Namespace 

que acaba de recibir un objeto de espacio de nombres, pero no se puede decir mucho acerca de lo que puede hacer con él. Hasta ahora sólo sé de la función internar eso aceptan un objeto Namespace

user=> (intern working-namespace 'my-var "somevalue") 
#'my-namespace/my-var 
1

bien, con la ayuda de este tipo, Michael Kohl, descubrí cómo cambiar a un espacio de nombres que tuvo lugar en una variable (read here for more details)

es así, aquí vamos:

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! 

aunque no creo que es clojure idiomática para volver a asignar las variables, se podría construir esto en una función que recibe el soporte de espacio de nombres var como parámetro

ahora para obtener el valor de una var dentro y fuera de ese espacio de nombres

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

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