zcaudate
zcaudate

Reputation: 14258

programmatically create new namespace and put vars in there from another namespace

Say I am in test.core and I want to create test.new-ns and stick a var called new-method in there. Is there a way to do that without leaving test.core?

This is what I want to do:

(ns test.core)

(create-ns 'test.new-ns)
(put-in-ns 'test.new-ns 'new-method {:meta 1} {:value 1})

 *ns* ;=> test.core
 test.new-ns/new-method ;;=> {:value 1}
 (meta #'test.new-ns/new-method) ;; => {:meta 1}

Upvotes: 1

Views: 226

Answers (2)

Daniel Neal
Daniel Neal

Reputation: 4173

I believe you're looking for intern.

Finds or creates a var named by the symbol name in the namespace ns (which can be a symbol or a namespace), setting its root binding to val if supplied. The namespace must exist. The var will adopt any metadata from the name symbol. Returns the var.

So for your example, it would go a little something like this:

(ns test.core)

(create-ns 'test.new-ns)

(intern 'test.new-ns 'new-method {:value 1})

Upvotes: 2

Michał Marczyk
Michał Marczyk

Reputation: 84379

create-ns actually exists in clojure.core and has exactly this signature.

As for put-in-ns, that's called intern; also, rather than accepting a metadata map as a separate argument, it transfers any metadata attached to the "name" symbol to the Var:

(intern 'test.new-ns (with-meta 'new-method {:meta 1}) {:value 1})

Reader meta works too, as long as you put it "inside the quote":

(intern 'test.new-ns ' ^{:meta 1} new-method {:value 1})

Upvotes: 3

Related Questions