Applying var or # 'to a list of functions in Clojure

I am trying to read metadata for a feature set in Clojure, but special var or reader forms do not work if they are not directly related to the character.

; this works
(var my-fn)

; this doesn't
(defn val-it [x] (var x))
(val-it my-fn)

Is there a way to make this work as part of another function?

+4
source share
2 answers

resolvereturns a Var or class object corresponding to the given character in the context of the current namespace. ns-resolveallows you to specify which namespace to allow.

(resolve 'my-fn)
;= #'some.ns/my-fn

If the character cannot be resolved to Var, returns nil.

+8
source

(var my-fn) , ( ).

, , var, .

, - , . , .

(defn meta-of
  "Returns a hashmap mapping the function objects in fn-objs to 
  a set of metadata of vars containing it."
  [fn-objs]
  (let [fn-objs (set fn-objs)]
    (reduce (fn [acc ns]
              (reduce (fn [acc var]
                        (let [val (var-get var)]
                          (cond-> acc
                                  (contains? fn-objs val)
                                  (update-in [val] (fnil conj #{}) (meta var)))))
                      acc
                      (vals (ns-interns ns)))) {} (all-ns))))
(def foo inc) ;; Now there are two vars that have the inc function as their value
(meta-of [inc])
{#<core$inc clojure.core$inc@66d7e31d>  ;; <- function object
 #{{:ns #<Namespace clojure.core>,  ;; <- metadata in clojure.core namespace
    :name inc,
    :file "clojure/core.clj",
    :column 1,
    :line 881,
    :arglists ([x]),
    :added "1.2",
    :inline #<core$inc__inliner clojure.core$inc__inliner@24f87069>,
    :doc
    "Returns a number one greater than num. Does not auto-promote\n  longs, will throw on overflow. See also: inc'"}
   {:ns #<Namespace user>,  ;; <- metadata in user namespace
    :name foo,
    :file "/tmp/form-init1078564431656334911.clj",
    :column 1,
    :line 1}}}
+2

Source: https://habr.com/ru/post/1536897/


All Articles