ClojureDocs

导航

命名空间

resolve

clojure.core

从 1.0 开始提供 ()
  • (resolve sym)
  • (resolve env sym)
same as (ns-resolve *ns* symbol) or (ns-resolve *ns* &env symbol)
8 Examples
user=> ((-> "first" symbol resolve) [1 2 3])
1
;; See also https://clojure.org/namespaces for information on namespaces in Clojure and how to inspect and manipulate them
user=> (resolve 'x)
nil
user=> (def x 1)
#'user/x
user=> (resolve 'x)
#'user/x

user=> (resolve 'join)
nil
user=> (use '[clojure.string :only [join]])
nil
user=> (resolve 'join)
#'clojure.string/join

user=> (join ", " ["a" "b"])
"a, b"
user=> ((resolve 'join) ", " ["a" "b"])
"a, b"
user=> (resolve 'Exception)
java.lang.Exception

user=> (type (resolve 'Exception))
java.lang.Class
;; Also resolve Array classes
(resolve (symbol "[I"))
;; [I
;; Also takes a set/map of symbols to ignore while resolving.

(defn replace-var [name value]
  (let [protected #{'+ '- '* '/}]
    (when (resolve protected name)
      (intern *ns* name value))))

(replace-var 'first last)
(first [1 2 3 4])
;; 4

;; plus is protected.
(replace-var '+ -)
(+ 1 1)
;; 2
;; Also works fine on namespaced symbols

;; some-ns
(def x 1)

;; other-ns
@(resolve 'some-ns/x)
;; 1
;; (resolve env sym) can be used to detect what
;; the user is referring to at macro time.

;; The implied macro arg &env contains local bindings
;; of symbols when the macro is called. Resolve checks
;; if the symbol is contained within env. If (contains? env sym)
;; is true, resolve returns nil, meaning the symbol not referring
;; to anything globally, but rather to a local binding.

;; See (source ns-resolve). It's literally just a when check on the env arg.

;; Essentially, it boils down to four cases with (resolve env sym):
;; 1. Resolve returning a var. User is referring to a global var.
;; 2. Resolve returning a class. User is referring to global class.
;; 3. Resolve returning nil, and sym is contained in &env.
;;    User is referring to something local.
;; 4. Resolve returning nil, and sym is not contained in &env.
;;    It's an unresolvable symbol.

;; The &env map can be further examined to see what exactly the
;; local binding is, but bewarned that this is entering Clojure
;; compiler territory.

(defmacro check-call
  "Checks if valid function call."
  [[sym & _ :as this]]
  (if (and (seq? this) (symbol? sym))
    (if-some [v (resolve &env sym)] ; Resolve with &env
      (if (var? v)
        (println "Calling function on var:" v)
        (println "Cannot call class as function:" v))
      (if (contains? &env sym)
        (println "Calling function on local binding:" sym)
        (println "Cannot call unresolvable symbol as function:" sym)))
    (println "Not function call.")))

(check-call (map inc (range 10)))

;; => Calling function on var: #'clojure.core/map

(check-call (java.util.Map))

;; => Cannot call class as function: java.util.Map

(let [map (fn [arg] (str "shadowed map " arg))]
  (check-call (map "foo"))) ; Calling the shadowed map, not clojure.core/map!

;; => Calling function on local binding: map

(check-call (foobar))

;; => Cannot call unresolvable symbol as function: foobar
See Also

Returns the var or Class to which a symbol will be resolved in the namespace (unless found in the ...

Added by gstamp

Returns a Symbol with the given namespace and name. Arity-1 works on strings, keywords, and vars.

Added by blx

Also reader macro: @ref/@agent/@var/@atom/@delay/@future/@promise. Within a transaction, returns t...

Added by MicahElliott

Resolves namespace-qualified sym per 'resolve'. If initial resolve fails, attempts to require sym's ...

Added by PEZ
0 Notes
No notes for resolve