【问题标题】:How do I get a list of public functions in a ClojureScript namespace?如何获取 ClojureScript 命名空间中的公共函数列表?
【发布时间】:2017-06-20 15:25:49
【问题描述】:

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

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

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

【问题讨论】:

    标签: clojurescript


    【解决方案1】:

    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,它可能会在高级编译中中断,但它可以工作。

    【讨论】:

    • 看起来clojure.repl/dir 打印了命名空间中的所有个公共变量。您将如何进一步过滤到函数?
    • 看看cljs.test/function?cljs.analyzer/named-public-vars的代码。也许这会对你有所帮助。我现在无法让它工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    相关资源
    最近更新 更多