bdesham
bdesham

Reputation: 16089

How do I access the name of the current namespace?

It seems that the *ns* object is available all the time under Clojure but not under ClojureScript. Is there an alternative way to access the name of the current namespace?

Motivation

I have a slew of calls like

(define-subscription ::something :other-namespace/something)

in which the two occurrences of something are redundant. I’d like to be able to write this in a more succinct form like (define-sub 'something), but in order to turn that shortened form into the full form I’d need to have a way to refer to the keyword ::something without using the :: syntactic sugar. It would be possible just to hard-code in the namespace name, but that feels unsatisfying.

Upvotes: 0

Views: 503

Answers (2)

Istvan Devai
Istvan Devai

Reputation: 4022

You can read the metadata associated with a var of the namespace you are interested in:

(defn get-current-namespace []
    (-> #'get-current-namespace meta :ns))

Or if you don't want to declare this function in the namespace itself, but need it as a utility method, you can create one like:

(defn namespace-of-var [a-var]
    (-> a-var meta :ns))

which you can call like:

cljs.user> (def a "hello!")
cljs.user> (namespace-of-var #'a)
cljs.user

Practically, you can call the namespace-of-var function from another function, passing in the function's own name as var parameter:

(defn function-in-another-namespace []
    (let [current-namespace (namespace-of-var #'function-in-another-namespace)]
        (prn (str "current namespace: " current-namespace))))

Upvotes: 2

akond
akond

Reputation: 16035

With a macro you should be able to do it:

(defmacro defsub [n]
    (let [x# (name n)]
        `(define-subscription (keyword ~x#) (keyword "other" ~x#))))

(defsub blah)

Upvotes: 0

Related Questions