de-narm
de-narm

Reputation: 29

Using clojure protocol across multiple namespaces

I'm currently implementing multiple types with the same protocol as the basis and would like to reduce the number of files one would need to include in the namespace in order to use them. To give an example:

basetype.clj

(defprotocol Base
  (do-something [obj]))

(deftype Basetype [obj]
  ...
  Base
   (do-something [obj] something-something))

second_type.clj

(ns project.second-type
  (:use project.basetype))

(deftype DifferentType [obj]
  ...
  Base
   (do-something [obj] something-slightly-different))

What I did achieve is that everything built for Basetype also works with DifferentType. However, I'd like to access the function do-something simply by including second_type.clj in a namespace instead of including both. Is there a way to achieve this?

Upvotes: 0

Views: 191

Answers (1)

leetwinski
leetwinski

Reputation: 17859

as i mentioned in my comment, you should be able to reexport any values from any namespace.

you could make up simple function like this:

(defn reexport [from-ns name]
  (ns-unmap *ns* name)
  (intern *ns* name @(ns-resolve from-ns name)))

(reexport 'project.basetype 'do-something)

or to reexport all the values from the given ns:

(defn reexport-all [from-ns]
  (run! (partial reexport from-ns) (map first (ns-publics from-ns))))

(reexport-all 'project.basetype)

in repl:

user> (ns x)
nil

x> (defn f [v] (inc v))
#'x/f

x> (ns y)
nil

y> (user/reexport 'x 'f)
#'y/f

y> (in-ns 'user)
#namespace[user]

user> (y/f 10)
11

user> (in-ns 'y)
#namespace[y]

y> (defn f2 [v] (dec v))
#'y/f2

y> (ns z)
nil

z> (user/reexport-all 'y)
nil

z> (in-ns 'user)
#namespace[user]

user> (z/f 1)
2

user> (z/f2 1)
0

Upvotes: 1

Related Questions