jvm.namespace

namespace inspection, evaluation, cleanup, and reload workflows

Inspect namespace mappings and memory, evaluate forms in controlled namespaces, and reload dependency-ordered namespace sets.

1    Overview

The namespace combines direct evaluation helpers with std.pipe tasks for listing, clearing, resetting, and reloading namespaces. Most task functions accept one namespace, a collection, or the default current namespace.

2    Walkthrough

2.1    Inspect a namespace

(require '[jvm.namespace :as namespace])

(namespace/list-publics 'jvm.namespace)
(namespace/list-interns 'jvm.namespace)
(namespace/list-imports 'jvm.namespace)
(namespace/list-aliases 'jvm.namespace)

2.2    Evaluate in context

(namespace/eval-ns 'example.scratch
  '(def answer 42))

(namespace/with-ns 'example.scratch
  answer)

(namespace/eval-temp-ns
  '(+ 1 2 3))

2.3    Reload a dependency set

reload sorts the supplied namespaces topologically before running the reload task. Use the clear functions narrowly; reset removes namespaces under a root and is intended for controlled development workflows.

(namespace/reload
 '[example.core example.api])

(namespace/loaded? 'example.core)
(namespace/list-in-memory 'example.core)

3    API



clear ^

Added 3.0

namespace clear all mappings and aliases task

v 3.0
(invoke/definvoke clear
  [:pipe {:template :namespace
          :params {:title "CLEAR NAMESPACE ALIASES AND MAPPINGS"
                   :parallel true}
          :main {:fn common/ns-clear}}])
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'str 'clojure.string)) (intern tmp 'hello 1) (ns/clear [(ns-name tmp)] {:return :summary}) => map?)

clear-aliases ^

Added 3.0

removes all namespace aliases

v 3.0
(invoke/definvoke clear-aliases
  [:pipe {:template :namespace
          :params {:title "CLEAR NAMESPACE ALIASES"
                   :parallel true}
          :main {:fn common/ns-clear-aliases}}])
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'str 'clojure.string)) (ns/clear-aliases [(ns-name tmp)] {:return :summary}) => map?)

clear-external-imports ^

Added 3.0

clears all external imports

v 3.0
(invoke/definvoke clear-external-imports
  [:pipe {:template :namespace
          :params {:title "CLEAR NAMESPACE ALIASES"
                   :parallel true}
          :main {:fn common/ns-clear-external-imports}}])
link
(with-temp-ns [tmp] (binding [*ns* tmp] (import java.io.File)) (ns/clear-external-imports [(ns-name tmp)] {:return :summary}) => map?)

clear-interns ^

Added 3.0

clears all interned vars in the namespace

v 3.0
(invoke/definvoke clear-interns
  [:pipe {:template :namespace
          :params {:title "CLEAR NAMESPACE INTERNS"
                   :parallel true}
          :main {:fn common/ns-clear-interns}}])
link
(with-temp-ns [tmp] (intern tmp 'hello 1) (ns/clear-interns [(ns-name tmp)] {:return :summary}) => map?)

clear-mappings ^

Added 3.0

removes all mapped vars in the namespace

v 3.0
(invoke/definvoke clear-mappings
  [:pipe {:template :namespace
          :params {:title "CLEAR NAMESPACE MAPPINGS"
                   :parallel true}
          :main {:fn common/ns-clear-mappings}}])
link
(with-temp-ns [tmp] (intern tmp 'join (fn [xs] (apply str xs))) (ns/clear-mappings [(ns-name tmp)] {:return :summary}) => map?)

clear-refers ^

Added 3.0

clears all refers in a namespace

v 3.0
(invoke/definvoke clear-refers
  [:pipe {:template :namespace
          :params {:title "CLEAR NAMESPACE refers"
                   :parallel true}
          :main {:fn common/ns-clear-refers}}])
link
(with-temp-ns [tmp] (binding [*ns* tmp] (clojure.core/refer 'clojure.string :only '[join])) (ns/clear-refers [(ns-name tmp)] {:return :summary}) => map?)

eval-ns ^

[ns forms]
Added 3.0

evaluates a list of forms in an existing namespace

v 3.0
(defn eval-ns
  ([ns forms]
   (binding [*ns* (the-ns ns)]
     (->> forms
          (mapv (fn [form] (eval form)))
          last))))
link
(require '[std.lib]) (eval-ns 'std.lib '[(long? 1)]) => true

eval-temp-ns ^

[forms]
Added 3.0

evaluates a list of forms in a temporary namespace

v 3.0
(defn eval-temp-ns
  ([forms]
   (let [sym (gensym)]
     (try
       (create-ns sym)
       (eval-ns sym (cons '(clojure.core/refer-clojure) forms))
       (finally (remove-ns sym))))))
link
(eval-temp-ns '[(def inc1 inc) (defn inc2 [x] (+ 1 x)) (-> 1 inc1 inc2)]) => 3 "All created vars will be destroyed after evaluation." (resolve 'inc1) => nil

list-aliases ^

Added 3.0

namespace list all aliases task

v 3.0
(invoke/definvoke list-aliases
  [:pipe {:template :namespace
          :params {:title "NAMESPACE ALIASES"
                   :parallel true}
          :main   {:fn clojure.core/ns-aliases}
          :item   {:post return-keys}}])
link
(ns/list-aliases '[jvm.namespace]) => map?

list-external-imports ^

Added 3.0

lists all external imports

v 3.0
(invoke/definvoke list-external-imports
  [:pipe {:template :namespace
          :params {:title "NAMESPACE IMPORTS"
                   :parallel true}
          :main {:fn common/ns-list-external-imports}
          :item {:post return-keys}}])
link
(ns/list-external-imports '[jvm.namespace] {:return :summary}) => map?

list-imports ^

Added 3.0

namespace list all imports task

v 3.0
(invoke/definvoke list-imports
  [:pipe {:template :namespace
          :params {:title "NAMESPACE IMPORTS"}
          :main {:fn clojure.core/ns-imports}
          :item {:post return-keys}}])
link
(ns/list-imports '[jvm.namespace] {:return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :total 482} => map?

list-in-memory ^

Added 3.0

namespace list all objects in memory task

v 3.0
(invoke/definvoke list-in-memory
  [:pipe {:template :namespace.memory
          :params {:title "NAMESPACE MEMORY OBJECTS"
                   :parallel true}
          :main   {:fn common/raw-in-memory}}])
link
(ns/list-in-memory 'jvm.namespace) (ns/list-in-memory '[jvm.namespace] {:print {:result false :summary false} :return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :objects 306, :functions 22} => map?

list-interns ^

Added 3.0

namespace list all interns task

v 3.0
(invoke/definvoke list-interns
  [:pipe {:template :namespace
          :params {:title "NAMESPACE INTERNS"
                   :parallel true}
          :main {:fn clojure.core/ns-interns}
          :item {:post return-keys}}])
link
(ns/list-interns '[jvm.namespace] {:return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :total 43} => map?

list-loaded ^

[] [inputs]
Added 4.0

list all loaded namespaces

v 4.0
(defn list-loaded
  ([]
   (list-loaded :all))
  ([inputs]
   (let [nss (common/ns-list)]
     (if (= :all inputs)
       nss
       (filter (fn [ns]
                 (some (fn [sym] (.startsWith (str ns)
                                              (str sym)))
                       inputs))
               nss)))))
link
(ns/list-loaded '[jvm.namespace]) => (contains ['jvm.namespace])

list-mappings ^

Added 3.0

namespace list all mappings task

v 3.0
(invoke/definvoke list-mappings
  [:pipe {:template :namespace
          :params {:title "NAMESPACE MAPPINGS"
                   :parallel true}
          :main {:fn clojure.core/ns-map}
          :item {:post return-keys}}])
link
(ns/list-mappings '[jvm.namespace] {:return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :total 3674} => map?

list-publics ^

Added 3.0

namespace list all publics task

v 3.0
(invoke/definvoke list-publics
  [:pipe {:template :namespace
          :params {:title "NAMESPACE PUBLICS"
                   :parallel true}
          :main {:fn clojure.core/ns-publics}
          :item {:post return-keys}}])
link
(ns/list-publics '[jvm.namespace] {:return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :total 43} => map?

list-refers ^

Added 3.0

namespace list all refers task

v 3.0
(invoke/definvoke list-refers
  [:pipe {:template :namespace
          :params {:title "NAMESPACE REFERS"
                   :parallel true}
          :main {:fn clojure.core/ns-refers}
          :item {:post return-keys}}])
link
(ns/list-refers '[jvm.namespace] {:return :summary}) ;;{:errors 0, :warnings 0, :items 5, :results 5, :total 3149} => map?

loaded? ^

Added 3.0

namespace check if namespace is loaded task

v 3.0
(invoke/definvoke loaded?
  [:pipe {:template :namespace.count
          :params {:title "NAMESPACE LOADED?"
                   :parallel true}
          :main {:fn common/ns-loaded?}}])
link
(ns/loaded? 'jvm.namespace) => true (ns/loaded? '[jvm.namespace]) => map?

namespace-template ^

NONE
(def namespace-template)
link

ns-context ^

[]
Added 3.0

gets the namespace context

v 3.0
(defn ns-context
  ([] *ns-context*))
link
(ns-context) => jvm.namespace.context.NamespaceContext

ns-vars ^

[ns]
Added 3.0

lists the vars in a particular namespace

v 3.0
(defn ns-vars
  ([ns]
   (vec (sort (keys (ns-publics ns))))))
link
(ns-vars 'jvm.namespace.context) => '[*ns-context* ->NamespaceContext map->NamespaceContext ns-context ns-vars reeval resolve-ns]

reeval ^

[] [ns]
Added 3.0

reevals all dependents of a namespace

v 3.0
(defn reeval
  ([]
   (reeval (.getName *ns*)))
  ([ns]
   (deps/dependents-refresh (ns-context) ns)))
link
(with-redefs [deps/dependents-refresh (fn [_ ns] [:refreshed ns])] (reeval 'jvm.namespace.context)) => [:refreshed 'jvm.namespace.context]

reload ^

[] [inputs]
Added 3.0

reloads all listed namespace aliases

v 3.0
(defn reload
  ([]
   (reload-task))
  ([inputs]
   (reload-task (dependent/sort-topo inputs))))
link
(with-redefs [ns/reload-task (fn [& _] :reloaded) dependent/sort-topo identity] (ns/reload '[jvm.namespace.dependent jvm.namespace.common])) => :reloaded

reload-all ^

Added 3.0

reloads all listed namespaces and dependents

v 3.0
(invoke/definvoke reload-all
  [:pipe {:template :namespace
          :params {:title "RELOADS NAMESPACE AND DEPENDENCIES"
                   :parallel true}
          :main {:fn common/ns-reload-all}}])
link
(with-redefs [common/ns-reload-all (fn [ns] nil)] (ns/reload-all '[jvm.namespace.common] {:return :summary})) => map?

reload-task ^

Added 4.1

reload task delegates to namespace reload

v 4.1
(invoke/definvoke reload-task
  [:pipe {:template :namespace
          :params {:title "RELOADS NAMESPACE"
                   :parallel false}
          :main {:fn common/ns-reload}}])
link
(with-redefs [common/ns-reload (fn [ns] nil)] (ns/reload-task '[jvm.namespace.common] {:return :summary})) => map?

reset ^

Added 3.0

deletes all namespaces under the root namespace

v 3.0
(invoke/definvoke reset
  [:pipe {:template :namespace.memory
          :params {:title "RESET NAMESPACE"
                   :parallel true
                   :print {:item true
                           :summary true}}
          :main {:fn common/ns-delete}}])
link
(let [sym (symbol "jvm.namespace.reset-temp")] (create-ns sym) (ns/reset [sym] {:return :summary}) => map?)

resolve-ns ^

[sym]
Added 3.0

resolves the namespace or else returns nil if it does not exist

v 3.0
(defn resolve-ns
  ([^clojure.lang.Symbol sym]
   (let [nsp  (.getNamespace sym)
         nsym (or  (and nsp
                        (symbol nsp))
                   sym)]
     (if nsym
       (f/suppress (do (require nsym) nsym))))))
link
(resolve-ns 'clojure.core) => 'clojure.core (resolve-ns 'clojure.core/some) => 'clojure.core (resolve-ns 'clojure.hello) => nil

return-keys ^

NONE
(def return-keys (comp vec sort keys))
link

unalias ^

Added 3.0

namespace unalias task

v 3.0
(invoke/definvoke unalias
  [:pipe {:template :namespace
          :params {:title "UNALIAS NAMESPACE SYMBOL"
                   :parallel true
                   :print {:result false
                           :summary false}}
          :arglists '([:args syms] [ :args syms])
          :main {:fn common/ns-unalias}}])
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'something 'clojure.string)) (ns/unalias [(ns-name tmp)] :args '[something]) => map?)

unmap ^

Added 3.0

namespace unmap task

v 3.0
(invoke/definvoke unmap
  [:pipe {:template :namespace
          :params {:title "UNMAP NAMESPACE SYMBOL"
                   :parallel true}
          :arglists '([:args syms] [ :args syms])
          :main {:fn common/ns-unmap}}])
link
(with-temp-ns [tmp] (intern tmp 'something 1) (ns/unmap [(ns-name tmp)] :args '[something]) => map?)

with-ns ^

[ns & forms]
Added 3.0

evaluates `body` forms in an existing namespace given by `ns`.

v 3.0
(defmacro with-ns
  ([ns & forms]
   `(binding [*ns* (the-ns ~ns)]
      ~@(map (fn [form] `(eval '~form)) forms))))
link
(require '[std.lib]) (with-ns 'std.lib (long? 1)) => true


+class-cache+ ^

NONE
(defonce ^java.util.concurrent.ConcurrentHashMap +class-cache+
  (query/apply-element DynamicClassLoader "classCache" []))
link

+namespaces+ ^

NONE
(defonce ^java.util.concurrent.ConcurrentHashMap +namespaces+
  (query/apply-element Namespace "namespaces" []))
link

+ns-clojure-imports+ ^

NONE
(def +ns-clojure-imports+
  #{java.util.concurrent.Callable
    clojure.lang.DynamicClassLoader
    java.math.BigInteger
    clojure.lang.Namespace
    java.math.BigDecimal
    clojure.lang.Compiler})
link

+rq+ ^

NONE
(defonce ^java.lang.ref.ReferenceQueue +rq+
  (query/apply-element DynamicClassLoader "rq" []))
link

group-in-memory ^

[results]
Added 3.0

creates human readable results from the class list

v 3.0
(defn group-in-memory
  ([results]
   (let [results (->> results
                      (map #(clojure.string/split % (re-pattern "\$")))
                      (map rest))
         anon?  (fn [[call _]]
                  (try (re-find #"^fn__*" call)
                       (catch Exception ex
                         true)))
         anons  (->> results (filter anon?) count)
         eval?  (fn [[call _]]
                  (try (re-find #"^evald+" call)
                       (catch Exception ex
                         true)))
         evals   (->> results (filter eval?) count)
         funcs   (->> results
                      (remove eval?)
                      (remove anon?)
                      (group-by first))
         fks     (sort (keys funcs))]
     (cond->> (keep (fn [fk]
                      (try
                        [(symbol (f/demunge fk)) (count (get funcs fk))]
                        (catch Throwable t)))
                    fks)
       (pos? anons) (cons ['ANON anons])
       (pos? evals) (cons ['EVAL evals])
       :then (vec)))))
link
(group-in-memory ["code.manage$add$1" "code.manage$add$2" "code.manage$sub$1" "code.manage$sub$2"]) => '[[add 2] [sub 2]]

ns-clear ^

[ns]
Added 3.0

clears all mappings and aliases in a given namespace

v 3.0
(defn ns-clear
  ([ns]
   (concat (ns-clear-aliases ns)
           (ns-clear-refers ns)
           (ns-clear-interns ns)
           (ns-clear-external-imports ns))))
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'str 'clojure.string) (clojure.core/refer 'clojure.string :only '[join]) (import java.io.File)) (intern tmp 'hello 1) (let [_ (doall (ns-clear tmp))] [(ns-aliases tmp) (ns-refers tmp) (ns-interns tmp) (ns-list-external-imports tmp)])) => [{} {} {} ()]

ns-clear-aliases ^

[ns]
Added 3.0

removes all namespace aliases

v 3.0
(defn ns-clear-aliases
  ([ns]
   (for [alias (keys (ns-aliases ns))]
     (do (clojure.core/ns-unalias ns alias)
         alias))))
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'str 'clojure.string) (alias 'set 'clojure.set)) [(set (ns-clear-aliases tmp)) (ns-aliases tmp)]) => [#{'str 'set} {}]

ns-clear-external-imports ^

[ns]
Added 3.0

clears all external imports

v 3.0
(defn ns-clear-external-imports
  ([ns]
   (mapv (fn [k]
           (clojure.core/ns-unmap ns k)
           k)
         (ns-list-external-imports ns))))
link
(ns-clear-external-imports *ns*) (ns-list-external-imports *ns*) => ()

ns-clear-interns ^

[ns]
Added 3.0

clears all interns in a given namespace

v 3.0
(defn ns-clear-interns
  ([ns]
   (mapv (fn [k]
           (clojure.core/ns-unmap ns k)
           k)
         (keys (ns-interns ns)))))
link
(with-temp-ns [tmp] (intern tmp 'hello 1) [(ns-clear-interns tmp) (ns-interns tmp)]) => [['hello] {}]

ns-clear-mappings ^

[ns]
Added 3.0

removes all mapped vars in the namespace

v 3.0
(defn ns-clear-mappings
  ([ns]
   (mapv (fn [k]
           (clojure.core/ns-unmap ns k)
           k)
         (keys (ns-map ns)))))
link
(with-temp-ns [tmp] (intern tmp 'join (fn [xs] (apply str xs))) [(some #{'join} (ns-clear-mappings tmp)) (contains? (ns-map tmp) 'join)]) => ['join false]

ns-clear-refers ^

[ns]
Added 3.0

clears all refers in a given namespace

v 3.0
(defn ns-clear-refers
  ([ns]
   (mapv (fn [k]
           (clojure.core/ns-unmap ns k)
           k)
         (keys (ns-refers ns)))))
link
(with-temp-ns [tmp] (binding [*ns* tmp] (clojure.core/refer 'clojure.string :only '[join])) [(ns-clear-refers tmp) (ns-refers tmp)]) => [['join] {}]

ns-delete ^

[ns]
Added 3.0

clears all namespace mappings and remove namespace from clojure environment

v 3.0
(defn ns-delete
  ([ns]
   (let [;; unload from libs
         _    (dosync (alter @#'clojure.core/*loaded-libs*
                             disj ns))

         ;; clear classloader cache
         results (->> (raw-in-memory ns)
                      (mapv (fn [k] (.remove +class-cache+ k)
                              k)))

         ;; unmap from global *namespaces
         nsp (.get +namespaces+ ns)
         _   (ns-clear nsp)
         _   (.remove +namespaces+ ns)]

     results)))
link
(let [sym (gensym "jvm.namespace.delete-test-") tmp (create-ns sym)] (intern tmp 'hello 1) (ns-delete sym) (contains? (set (ns-list)) sym)) => false

ns-in-memory ^

[ns]
Added 3.0

retrieves all the clojure namespaces currently in memory

v 3.0
(defn ns-in-memory
  ([ns]
   (->> (raw-in-memory ns)
        (group-in-memory))))
link
(ns-in-memory 'code.manage) ;;[[EVAL 2]] => coll?

ns-list ^

[]
Added 3.0

returns all existing clojure namespaces

v 3.0
(defn ns-list
  ([]
   (keys +namespaces+)))
link
(ns-list) => coll?

ns-list-external-imports ^

[ns]
Added 3.0

lists all external imports

v 3.0
(defn ns-list-external-imports
  ([ns]
   (->> (ns-imports *ns*)
        (remove (fn [[k ^Class v]]
                  (or (.startsWith (.getName v) "java.lang")
                      (+ns-clojure-imports+ v))))
        (map first))))
link
(import java.io.File) (ns-list-external-imports *ns*) => '(File)

ns-loaded? ^

[ns]
Added 3.0

checks if the namespaces is currently active

v 3.0
(defn ns-loaded?
  ([ns]
   (boolean (get @@#'clojure.core/*loaded-libs* ns))))
link
(ns-loaded? 'jvm.namespace.common) => true

ns-reload ^

[ns]
Added 3.0

reloads aliases in current namespace

v 3.0
(defn ns-reload
  ([ns]
   (require ns :reload)))
link
(do (ns-reload 'jvm.namespace.common) (ns-loaded? 'jvm.namespace.common)) => true

ns-reload-all ^

[ns]
Added 3.0

reloads aliases and dependents in current namespace

v 3.0
(defn ns-reload-all
  ([ns]
   (require ns :reload-all)))
link
(do (ns-reload-all 'jvm.namespace.common) (ns-loaded? 'jvm.namespace.common)) => true

ns-unalias ^

[ns refer]
Added 3.0

removes given aliases in namespaces

v 3.0
(defn ns-unalias
  ([ns refer]
   (cond (symbol? refer)
         (do (clojure.core/ns-unalias ns refer)
             refer)

         (coll? refer)
         (mapv #(ns-unalias ns %) refer))))
link
(with-temp-ns [tmp] (binding [*ns* tmp] (alias 'str 'clojure.string)) [(ns-unalias tmp 'str) (ns-aliases tmp)]) => ['str {}]

ns-unmap ^

[ns refer]
Added 3.0

removes given mapped elements in namespaces

v 3.0
(defn ns-unmap
  ([ns refer]
   (cond (symbol? refer)
         (do (clojure.core/ns-unmap ns refer)
             refer)

         (coll? refer)
         (mapv #(ns-unmap ns %) refer))))
link
(with-temp-ns [tmp] (intern tmp 'hello 1) [(ns-unmap tmp 'hello) (contains? (ns-map tmp) 'hello)]) => ['hello false]

raw-in-memory ^

[ns]
Added 3.0

returns a list of keys representing objects

v 3.0
(defn raw-in-memory
  ([ns]
   (->> +class-cache+
        (keep (fn [[k v]]
                (if (or (= ns k)
                        (.startsWith ^String k (str ns "$")))
                  k))))))
link
(raw-in-memory 'code.manage) ;;("code.manage$eval6411" "code.manage$eval6411$loading__5569__auto____6412") => coll?


*ns-context* ^

NONE
(defonce ^:dynamic *ns-context* (NamespaceContext.))
link

->NamespaceContext ^

[]

NONE
(impl/defimpl NamespaceContext []
  :suffix "-ns"
  :protocols [std.protocol.deps/IDeps
              protocol.deps/IDepsMutate])
link

NamespaceContext ^

NONE
(impl/defimpl NamespaceContext []
  :suffix "-ns"
  :protocols [std.protocol.deps/IDeps
              protocol.deps/IDepsMutate])
link

add-entry-ns ^

[context ns _ _]

NONE
(defn- add-entry-ns
  ([context ns _ _]
   (require ns)
   context))
link

get-deps-ns ^

[_ ns]

NONE
(defn- get-deps-ns
  ([_ ns]
   (->> (vals (ns-aliases ns))
        (map #(.getName ^clojure.lang.Namespace %)))))
link

get-entry-ns ^

[_ ns]

NONE
(defn- get-entry-ns
  ([_ ns] (the-ns ns)))
link

list-entries-ns ^

[_]

NONE
(defn- list-entries-ns
  ([_]
   (common/ns-list)))
link

map->NamespaceContext ^

[m__7997__auto__]

NONE
(impl/defimpl NamespaceContext []
  :suffix "-ns"
  :protocols [std.protocol.deps/IDeps
              protocol.deps/IDepsMutate])
link

ns-context ^

[]
Added 3.0

gets the namespace context

v 3.0
(defn ns-context
  ([] *ns-context*))
link
(ns-context) => jvm.namespace.context.NamespaceContext

ns-vars ^

[ns]
Added 3.0

lists the vars in a particular namespace

v 3.0
(defn ns-vars
  ([ns]
   (vec (sort (keys (ns-publics ns))))))
link
(ns-vars 'jvm.namespace.context) => '[*ns-context* ->NamespaceContext map->NamespaceContext ns-context ns-vars reeval resolve-ns]

reeval ^

[] [ns]
Added 3.0

reevals all dependents of a namespace

v 3.0
(defn reeval
  ([]
   (reeval (.getName *ns*)))
  ([ns]
   (deps/dependents-refresh (ns-context) ns)))
link
(with-redefs [deps/dependents-refresh (fn [_ ns] [:refreshed ns])] (reeval 'jvm.namespace.context)) => [:refreshed 'jvm.namespace.context]

refresh-entry-ns ^

[context ns]

NONE
(defn- refresh-entry-ns
  ([context ns]
   (common/ns-reload ns)
   context))
link

remove-entry-ns ^

[context ns]

NONE
(defn- remove-entry-ns
  ([context ns]
   (common/ns-delete ns)
   context))
link

resolve-ns ^

[sym]
Added 3.0

resolves the namespace or else returns nil if it does not exist

v 3.0
(defn resolve-ns
  ([^clojure.lang.Symbol sym]
   (let [nsp  (.getNamespace sym)
         nsym (or  (and nsp
                        (symbol nsp))
                   sym)]
     (if nsym
       (f/suppress (do (require nsym) nsym))))))
link
(resolve-ns 'clojure.core) => 'clojure.core (resolve-ns 'clojure.core/some) => 'clojure.core (resolve-ns 'clojure.hello) => nil


ns-all-dependents ^

[ns input]
Added 3.0

gets all dependencies

v 3.0
(defn ns-all-dependents
  ([ns input]
   (loop [acc {ns (ns-dependents ns input)}]
     (let [curr (set (keys acc))
           next (apply clojure.set/union (vals acc))
           diff (clojure.set/difference next curr)]
       (if (empty? diff)
         acc
         (recur (merge acc (ns-level-dependents diff input))))))))
link
(ns-all-dependents 'std.lib.sort '[hara]) => map?

ns-dependents ^

[ns input]
Added 3.0

finds dependent namespaces

v 3.0
(defn ns-dependents
  ([ns input]
   (set (filter #(ns-has-deps % ns) (ns-select input)))))
link
(ns-dependents 'std.lib.sort '#{jvm.namespace.dependent}) => '#{jvm.namespace.dependent}

ns-has-deps ^

[ns test]
Added 3.0

checks if current namespace depends on `test`

v 3.0
(defn ns-has-deps
  ([ns test]
   (let [deps (->>  (vals (ns-aliases ns))
                    (map #(.getName ^clojure.lang.Namespace %))
                    set)]
     (boolean (deps test)))))
link
(ns-has-deps 'jvm.namespace.dependent 'std.lib.sort) => true

ns-level-dependents ^

[nss input]
Added 3.0

arranges dependent namespaces in map

v 3.0
(defn ns-level-dependents
  ([nss input]
   (reduce (fn [out ns]
             (assoc out ns (ns-dependents ns input)))
           {}
           nss)))
link
(ns-level-dependents '#{std.lib.sort} '#{jvm.namespace.dependent}) => '{std.lib.sort #{jvm.namespace.dependent}}

ns-select ^

[input] [input nss]
Added 3.0

selects a bunch of namespaces

v 3.0
(defn ns-select
  ([input]
   (ns-select input (common/ns-list)))
  ([input nss]
   (ut/select-inputs {:item {:list (fn [_ _] nss)}}
                     {}
                     {}
                     input)))
link
(ns-select [(.getName *ns*)]) => '[jvm.namespace.dependent-test]

reeval ^

[] [input] [ns input]
Added 3.0

reevaluates all files dependent on current

v 3.0
(defn reeval
  ([]
   (reeval (.getName *ns*) :all))
  ([input]
   (reeval (.getName *ns*) input))
  ([ns input]
   (->> (ns-all-dependents ns input)
        (sort/topological-sort)
        (reverse)
        (mapv #(doto % (require :reload))))))
link
(->> (reeval '#{jvm.namespace.dependent}) (map str)) => ["jvm.namespace.dependent-test"]

sort-topo ^

[nss]
Added 4.1

topologically sorts namespaces by dependency order

v 4.1
(defn sort-topo
  [nss]
  (let [nss (set (map symbol nss))
        graph (reduce (fn [acc ns]
                        (let [deps (->> (vals (ns-aliases ns))
                                        (map #(.getName ^clojure.lang.Namespace %))
                                        (filter nss)
                                        set)]
                          (assoc acc ns deps)))
                      {}
                      nss)]
    (sort/topological-sort graph)))
link
(require '[jvm.namespace.dependent]) (sort-topo '[jvm.namespace.dependent-test jvm.namespace.dependent]) => '[jvm.namespace.dependent jvm.namespace.dependent-test]


eval-ns ^

[ns forms]
Added 3.0

evaluates a list of forms in an existing namespace

v 3.0
(defn eval-ns
  ([ns forms]
   (binding [*ns* (the-ns ns)]
     (->> forms
          (mapv (fn [form] (eval form)))
          last))))
link
(require '[std.lib]) (eval-ns 'std.lib '[(long? 1)]) => true

eval-temp-ns ^

[forms]
Added 3.0

evaluates a list of forms in a temporary namespace

v 3.0
(defn eval-temp-ns
  ([forms]
   (let [sym (gensym)]
     (try
       (create-ns sym)
       (eval-ns sym (cons '(clojure.core/refer-clojure) forms))
       (finally (remove-ns sym))))))
link
(eval-temp-ns '[(def inc1 inc) (defn inc2 [x] (+ 1 x)) (-> 1 inc1 inc2)]) => 3 "All created vars will be destroyed after evaluation." (resolve 'inc1) => nil

with-ns ^

[ns & forms]
Added 3.0

evaluates `body` forms in an existing namespace given by `ns`.

v 3.0
(defmacro with-ns
  ([ns & forms]
   `(binding [*ns* (the-ns ~ns)]
      ~@(map (fn [form] `(eval '~form)) forms))))
link
(require '[std.lib]) (with-ns 'std.lib (long? 1)) => true

with-temp-ns ^

[& forms]
Added 3.0

evaluates `body` forms in a temporary namespace.

v 3.0
(defmacro with-temp-ns
  ([& forms]
   `(try
      (create-ns 'sym#)
      (let [res# (with-ns 'sym#
                   (clojure.core/refer-clojure)
                   ~@forms)]
        res#)
      (finally (remove-ns 'sym#)))))
link
(with-temp-ns (def inc1 inc) (defn inc2 [x] (+ 1 x)) (-> 1 inc1 inc2)) => 3 "All created vars will be destroyed after evaluation." (resolve 'inc1) => nil