如何获取 ClojureScript 命名空间中 public 函数的列表?
How do I get a list of public functions in a ClojureScript namespace?
我想从另一个命名空间获取 public 函数的列表,以便它们可以作为命令公开。
Clojure 的 similar question 似乎很接近,但似乎不适用于 ClojureScript。
有 Clojurescript 的答案,但它们要么只显示如何将它们打印到 REPL,要么 return 所有成员而不是仅 public 公开的成员。
ClojureScript 没有 resolve
function. It is possible to mimic the behavior using hacks, e.g., this one:
(defn ->js [var-name]
(-> var-name
(clojure.string/replace #"/" ".")
(clojure.string/replace #"-" "_")))
(defn invoke [function-name & args]
(let [f (js/eval (->js function-name))]
(apply f args)))
您链接的第二个问题的答案涉及 clojure.repl/dir
打印
的函数
a sorted directory of public vars in a namespace.
如果你可以打印它们,你可以用with-out-str
把它们变成一个字符串。
现在假设我们有一个名为 demo.core
的名称空间和一个名为 add
的 public 函数:
(ns demo.core)
(defn add [a b]
(println "hello from add")
(+ a b))
我们可以从 demo.core
中检索 public fns 作为字符串,如下所示:
(defn public-fns
"Returns coll of names of public fns in demo.core"
[]
(as-> (with-out-str (clojure.repl/dir demo.core)) public-fns
(clojure.string/split public-fns #"\n")
(map (fn [s] (str "demo.core/" s)) public-fns)))
所以使用 with-out-str
我们将它们变成一个字符串列表,然后在换行符上拆分,然后在 public 函数的名称前加上 "demo.core".
然后,使用我们之前创建的 invoke
函数,我们可以获得 add
并使用参数 1 和 2 调用它:
(invoke (first (public-fns)) 1 2)
;; "hello from add"
;; => 3
这一切都非常 hacky,在高级编译中可能会出错,但它确实有效。
我想从另一个命名空间获取 public 函数的列表,以便它们可以作为命令公开。
Clojure 的 similar question 似乎很接近,但似乎不适用于 ClojureScript。
ClojureScript 没有 resolve
function. It is possible to mimic the behavior using hacks, e.g., this one:
(defn ->js [var-name]
(-> var-name
(clojure.string/replace #"/" ".")
(clojure.string/replace #"-" "_")))
(defn invoke [function-name & args]
(let [f (js/eval (->js function-name))]
(apply f args)))
您链接的第二个问题的答案涉及 clojure.repl/dir
打印
a sorted directory of public vars in a namespace.
如果你可以打印它们,你可以用with-out-str
把它们变成一个字符串。
现在假设我们有一个名为 demo.core
的名称空间和一个名为 add
的 public 函数:
(ns demo.core)
(defn add [a b]
(println "hello from add")
(+ a b))
我们可以从 demo.core
中检索 public fns 作为字符串,如下所示:
(defn public-fns
"Returns coll of names of public fns in demo.core"
[]
(as-> (with-out-str (clojure.repl/dir demo.core)) public-fns
(clojure.string/split public-fns #"\n")
(map (fn [s] (str "demo.core/" s)) public-fns)))
所以使用 with-out-str
我们将它们变成一个字符串列表,然后在换行符上拆分,然后在 public 函数的名称前加上 "demo.core".
然后,使用我们之前创建的 invoke
函数,我们可以获得 add
并使用参数 1 和 2 调用它:
(invoke (first (public-fns)) 1 2)
;; "hello from add"
;; => 3
这一切都非常 hacky,在高级编译中可能会出错,但它确实有效。