Anton Harald
Anton Harald

Reputation: 5934

Access requirements from outside of the namespace

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

Answers (1)

noisesmith
noisesmith

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

Related Questions