如何在ClojureScript命名空间中获取公共函数列表?

时间:2017-06-20 15:25:49

标签: clojurescript

我想从另一个命名空间获取公共函数列表,以便它们可以作为命令公开。

Clojure的similar question似乎很接近,但似乎不适用于ClojureScript。

Another question有Clojurescript的答案,但是他们要么只展示如何将它们打印到REPL,要么返回所有成员而不仅仅是公开的成员。

1 个答案:

答案 0 :(得分:2)

ClojureScript没有resolve功能。可以使用黑客来模仿行为,例如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函数

  

命名空间中公共变量的排序目录。

如果您可以打印它们,可以将它们变成带有with-out-str的字符串。

现在让我们假设我们有一个名为demo.core的命名空间,其中包含一个名为add的公共函数:

(ns demo.core)

(defn add [a b]
  (println "hello from add")
  (+ a b))

我们可以将demo.core中的公共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我们将它们转换为字符串列表,然后在换行符上拆分,然后在" demo.core"之前添加公共函数的名称。

然后,使用我们之前创建的invoke函数,我们可以获得add并使用参数1和2调用它:

(invoke (first (public-fns)) 1 2)
;; "hello from add"
;; => 3

这非常hacky,它可能会在高级编译中中断,但它可以工作。