Reputation: 2513
In Clojure, how do I get the name of the namespace in which variables and functions are named? For example, improving the following:
(ns my-ns)
(def namespace-name "my-ns")
The problem with the above is that if I want to change the name of my-ns, I have to change the definition of namespace-name as well
Upvotes: 14
Views: 4817
Reputation: 4169
ok, with the help of this guy, Michael Kohl, i found out how to switch to a namespace held in a variable (read here for more details)
so, here we go:
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!
although i don't think it is idiomatic clojure to reassign variables, you could build this into a function that gets the holder var for namespace as parameter
now to get the value of a var inside and outside that namespace
user=> (intern working-namespace 'some-var "my value")
#'other-namespace/some-var
user=> (var-get (intern working-namespace 'some-var))
"my value"
Upvotes: 1
Reputation: 4169
to create and store a namespace, you can do:
user=> (def working-namespace (create-ns 'my-namespace))
#'user/working-namespace
user=> working-namespace
#<Namespace my-namespace>
user=> (class working-namespace)
clojure.lang.Namespace
you just got a Namespace object, but i can't tell you very much about what you can do with it. so far i only know of the function intern thats accept a Namespace object
user=> (intern working-namespace 'my-var "somevalue")
#'my-namespace/my-var
Upvotes: 3
Reputation: 91554
the current namespace is stored in
*ns*
since your function is evaluated at runtime you will get what ever that value of * ns * is when you call it.
so if you may want to save a copy of it.
Upvotes: 9
Reputation: 2513
A simple modification of Arthur's answer works well.
(def namespace-name (ns-name *ns*))
However I want to warn Clojure beginners that
(defn namespace-name [] (ns-name *ns*))
will not work for the purposes of this question, since *ns* is bound dynamically.
Upvotes: 14