views:

83

answers:

4

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

+2  A: 

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.

Arthur Ulfeldt
Do you mean (def namespace-name (ns-name \*ns\*)) ?
chris
I type *ns* and it shows up as italics? how to I write this so SO displayed it literally?
Arthur Ulfeldt
ahh it did it again! * ns *
Arthur Ulfeldt
`*ns*` can be written surrounded with backticks, I guess
Peter Tillemans
+3  A: 

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.

chris
But something along the line (defmacro defns-name [name] `(def ~name (ns-name *ns*))) and then call (defns-name namespace-name) would work.
Nicolas Oury
+2  A: 

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
Belun
A: 

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"
Belun