Reputation: 5934
Imagine there is the following require-statement inside a namespace:
(ns my.core
(:require '[mylib.sth :as thing]))
(def somevar 123)
Is there a way to access mylib.sth via thing
also from outside this namespace? I mean to somehow get the same behavior as for the definition somevar:
(ns somethingelse)
my.core/somevar
;; =123
(my.core/thing/myf "param") ;; something like this
;; ...
Upvotes: 0
Views: 68
Reputation: 20194
resolve
and ns-resolve
were made for this situation.
They will return nil if the symbol is not found, otherwise they return the var, which you can deref in order to get the current bound value.
user=> (ns my.test)
nil
my.test=> (def hidden 5)
#'my.test/hidden
my.core=> (ns my.core (:require [my.test :as t]))
nil
my.core=> (in-ns 'user)
#object[clojure.lang.Namespace 0x25930632 "user"]
user=> @(resolve 'my.test/hidden)
5
user=> @(ns-resolve 'my.core 't/hidden)
5
This works, but it's also a last resort. It should be reserved for situations where you are writing code that uses namespaces and bindings that you expect to find at run time that cannot be accessible at compile time. For example I use resolve
to avoid transitive AOT of my project while compiling a stub that is callable from Java; the stub -main
invokes require
and then resolve
at runtime, using the resolved values to access the real code.
If all you are looking for is a convenience or syntactic shortcut, the better option is to explicitly require a namespace if you want to use its values.
Upvotes: 1