Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating an alias to another Clojure namespace

I have some private functions in one namespace that I would like to include in a second namespace. e.g.

(ns one)

(defn ^:private foo 
  "A docstring"
  [x] (* x 2))

And the second namespace needs to create an alias to this:

(ns two)

(def foo ???)

(foo 3)   ;; should work as if the function in namespace one was called
=> 6

Ideally I'd like to preserve the docstring so I don't have to maintain it in two places. Also I'd like to have the option to either use the same name or a different name.

The reason for this requirement is as follows: the functionality is needed/used in namespace one. one is a dependency of two, and since we can't have circular dependencies it won't work to define foo within two itself. two is the public API, so foo needs to be publicly part of the two namespace.

What's the best way to achieve this?

like image 288
mikera Avatar asked Jul 31 '12 08:07

mikera


1 Answers

How about this:

(ns one)

(defn- foo 
  "A docstring"
  [x] (* x 2))

(ns two)

(def foo-alias #'one/foo)
(alter-meta! #'foo-alias merge (select-keys (meta #'one/foo) [:doc :arglists]))

The trick is to not resolve the symbol 'one/foo, hence avoiding to trigger the private flag on its metadata. Then after aliasing foo in your second namespace, you simply cherry pick the metadata you want to keep from the previous definition.

like image 115
Jean-Louis Giordano Avatar answered Oct 21 '22 23:10

Jean-Louis Giordano