2010-09-21 19 views
9

W Clojure, jak uzyskać nazwę przestrzeni nazw, w której zmienne i funkcje są nazywane? Na przykład, poprawa następuje:Clojure: odnosząc się do nazwy przestrzeni nazw

(ns my-ns) 

(def namespace-name "my-ns") 

Problem z powyższego jest to, że jeśli chcę zmienić nazwę mojego-ns, muszę zmienić definicję przestrzeni nazw nazwy oraz

Odpowiedz

11

Prosta modyfikacja odpowiedzi Artura działa dobrze.

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

Jednak chcę ostrzec Clojure początkujących że

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

nie będzie pracować dla celów tego pytania, ponieważ * ns * jest związany dynamicznie.

+2

Ale coś wzdłuż linii (defmacro defns-name [name] '(def ~ nazwa (ns-nazwa * ns *))), a następnie zadzwonić (defns-nazwa-nazwy-nazwy) będzie działać. –

+0

Markdown zjadł gwiazdki wokół 'ns' w komentarzu Nicolas powyżej: powinien przeczytać:' (defmacro defns-name [name] \ '(def ~ name (ns-name * ns *)))'. –

6

się prąd nazw są przechowywane w

*ns* 

ponieważ czynność jest oceniana w czasie wykonywania dostaniesz co kiedykolwiek że wartość * ns * kiedy to nazwać.

, więc jeśli chcesz zachować kopię.

+0

Czy masz na myśli (def przestrzeni nazw (NS-name-name \ * ns \ *))? – chris

+0

Wpisuję * ns * i pojawia się ona jako kursywę? jak to napisać, więc SO pokazał to dosłownie? –

+0

ahh to znowu zrobiło! * ns * –

3

do tworzenia i zapisywania nazw, można zrobić:

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

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

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

po prostu dostał obiekt Namesepace, ale nie mogę powiedzieć, że bardzo dużo o tym, co można z nim zrobić. Do tej pory tylko wiedzieć funkcji intern ów zaakceptować obiekt Namesepace

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

ok, z pomocą tego faceta, Michaela Kohla, okazało się, jak przejść do nazw, która odbyła się w zmiennej (read here for more details)

tak, jedziemy:

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! 

chociaż nie sądzę, że jest idiomatyczne clojure aby przypisać zmienne, można zbudować to do funkcji, która ją właścicielowi var dla nazw jako parametr

teraz, aby uzyskać wartość var ​​na zewnątrz i wewnątrz tej przestrzeni nazw

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

user=> (var-get (intern working-namespace 'some-var)) 
"my value" 
Powiązane problemy