2010-09-21 14 views
9

Wie bekomme ich in Clojure den Namen des Namensraums, in dem Variablen und Funktionen benannt sind? Zum Beispiel der Verbesserung des folgenden:Clojure: Verweis auf den Namen des Namensraums

(ns my-ns) 

(def namespace-name "my-ns") 

Das Problem mit der oben ist, dass, wenn ich den Namen meines ns ändern will, ich habe die Definition von Namespace-Namen

Antwort

11

Eine einfache Änderung der Antwort Arthurs funktioniert gut.

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

Allerdings möchte ich Clojure Anfänger warnen, dass

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

wird nicht für die Zwecke dieser Frage arbeiten, da * ns * gebunden ist dynamisch.

+2

Aber etwas auf der Linie (defmacro defns-name [name] '(def ~ name (ns-name * ns *))) und dann call (defns-name namespace-name) würde funktionieren. –

+0

Abschriften aßen die Sterne um 'ns' in Nicolas Kommentar oben: sollte lauten:' (defmacro defns-name [name] \ '(def ~ Name (ns-name * ns *)))'. –

6

als auch die sie ändern aktuelle Namespace wird in

gespeichert
*ns* 

da Ihre Funktion zur Laufzeit ausgewertet wird, die Sie jemals, dass Wert von * ns, was * ist, wenn Sie es nennen.

also, wenn Sie eine Kopie davon speichern möchten.

+0

Wollen Sie damit sagen bekommen (def Namespace-Namen (ns-name \ * ns \ *))? – chris

+0

Ich tippe * ns * und es erscheint als Kursivschrift? Wie schreibe ich das so, SO zeigte es wörtlich? –

+0

ahh es tat es wieder! * ns * –

3

einen Namespace zu erstellen und zu speichern, können Sie tun:

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

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

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

Sie ein Namespace-Objekt nur bekam, aber ich kann Ihnen nicht sehr viel sagen über das, was man damit machen kann. bisher nur i die Funktion kenne intern das ist ein Namespace-Objekt

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

ok, mit Hilfe dieses Kerl, Michael Kohl akzeptieren, fand ich heraus, wie zu einem Namespace in einer Variablen gehalten wechseln (read here for more details)

so, hier gehen wir:

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! 

obwohl ich glaube nicht, dass es idiomatisch clojure ist Variablen neu zuordnen, können Sie diese in eine Funktion bauen könnte, die den Halter var für Namespace als Parameter bekommt

jetzt den Wert eines var innerhalb und außerhalb dieses Namensraum

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

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